Xamarin Android Activities and Disposing of Disposables - xamarin

I've found that whilst there are a lot of tutorials on Xamarin Android, there does not seem to be a great deal on how to dispose of resources. More particularly, when they are disposed of.
For example, in the OnCreate handler of an activity, I am making several Rx subscriptions, each of which returns an IDisposable. I have tried to dispose of those in various other handlers (e.g. OnDestroy), but those handlers never get invoked. But the subscriptions seem to pile up because OnCreate runs every time the activity is navigated to.
In addition to those subscriptions, there's all the UI controls (TextViews, Buttons etc.) which I am assigning to class-level variables (fields). And those also implement IDisposable.
For all I know, I've got memory leaks all over the place.
Is there a guidance on this anywhere?

#SushiHangover is correct (thanks Sushi). OnPause and OnResume were the events I was after. I also had a bit of a challenge in that when I clicked my custom "Back to Start" button, I needed to go right back to the start screen (skipping the intermediate screen along the way).
The way to do that is use the ClearTop ActivityFlag (Android.Content.ActivityFlags.ClearTop) when starting the Home screen activity. Raw Android code version of this can be seen here https://stackoverflow.com/a/5794572/540156
When you do that, you can clean things up on the activities which get popped off the back-stack as they get popped (in the OnDestroy handler, from recollection).

Related

Xamarin.Forms equivalent to overriding iOS's SendEvent

I'm working on inactivity detection.
I have successfully done so in iOS by subclassing UIApplication and overriding SendEvent as outlined here.
I know I could implement this separately for both iOS and Android, but I'd rather have a cross-platform Forms approach by intercepting all touch events and resetting my timers. I'd rather not have to add a touch event handler to all my pages either.
I was unable to find a cross platform approach. I was able to accomplish this by leaving the timer related information in core Forms project and implement the touch event handlers separately for iOS and Android. I handled the iOS touch events as outlined in the link in the OP, but for Android I took the approach of subclassing Activity due to the presence of the OnUserInteraction() method.
Initially I thought I would have to force Xamarin to use my subclassed Activity for all pages that I use in Xamarin, but I was mistaken. AdamMeaney over on the Xamarin forums was able to help with providing a solution for the Android side of things with regards to subclassing an Android activity. As it turns out, Xamarin only uses one Activity which inherits from Xamarin.Forms.Platform.Android.FormsAppCompatActivity. I used the MainAcitivty provided by Xamarin in the Droid project. From there, overriding the OnUserInteraction() proved to be quite simple:
public override void OnUserInteraction()
{
base.OnUserInteraction();
//Do other stuff
}
It would seem to me that all you really have to do on the platform side is get notified whenever a new touch event occurs. Unless I am missing something it seems you can do all of the timer stuff in the PCL core Forms project and call that code from the platform specific code that runs when a touch is detected.
So if on Android ( I did not verify, but I would assume so) there is a similar way to handle any touch, device wide, then it would seem that all you have to do is implement that event handler, as you did for iOS, and call into your Forms core code to handle the timer(s).
To clarify: On the platform side, just handle the touch events globally and then call into code in the Forms core thus only having to implement the timer functionality once. Or so it would seem unless I am missing something.
If you want to make a feature request for Xamarin Form, please do so at Xamarin's user voice page: xamarin.uservoice.com
I suspect Forms would just have to do as outlined above... handle device wide touches on each platform and then have a virtual method in Forms core code that is called whenever a touch occurs.

Appcelerator controller appear/disapear methods

I'm pretty new to Appcelerator and was wondering what the listeners for the view life cycle are?
For example, if I wanted to detect the iOS viewWillAppear and viewDidDisappear methods, or Androids OnResume, OnPause methods, then how would I do this the "Appcelerator" way?
I've searched around on the web, but only able to find in the Titanium documentation info about the application state such as Active, Suspended, ect. I need a controller, or window, specific listener to react to.
Thanks!
Titanium abstracts those events for you - so you don't have to worry about writing them for iOS/Android each.
Check out the Titanium.App documentation (http://docs.appcelerator.com/platform/latest/#!/api/Titanium.App). You can see what events are available at the app level (of course, each Titanium components has it's own events - but those are at app level).
If I understand your question, the relevant events for you are paused and resumed - when the app goes in the background and then back to foreground.

Google Play Games notifications not visible

I've looked through all questions on SO about Google Play Games, but looks like I'm the only one having problems now.
Using new GPG with Games.Achievements.unlock(), the achievement notification isn't showing up. I can see that achievement is unlocked when checking in unlocked achievements list, but that badge - it just doesn't show up!
The app isn't published, but has all the achievements correctly set up in Play Store. other GPG features seem to work fine, but they usually do not show notification (like Leaderboards)
And another issue that might be actually related to this. The initial login popup, the one that allows to pick an account when you have several of them on the device - sometimes it ends up being behind the app screen. And when you quit the app it keeps sitting on the device screen until you close it by picking Cancel. Not sure, this might be a debug issue due to app being force-closed on every next installation, but still.
Any ideas? How Achievement badge can end up being invisible all the time?
You may need to try changing the popup view, depending on which implementation you have used, this is the basegameutils method:
Games.setViewForPopups(getApiClient(), getWindow().getDecorView().findViewById(android.R.id.content));
Depending on your code, you may need to use a different view.
Try this in the activity view in which you want the notifications to be seen : Games.setViewForPopups(getApiClient(), getWindow().getDecorView().findViewById(android.R.id.content));
The issue was that I was calling Games.Achievements.unlock(mGoogleApiClient, context.getResources().getString(R.string.achievement_pro)); from a helper class. The context that I passed was of MainActivity.class, however I actually intended to show the achievements being unlocked in my GameScreen.class and not the MainActivity.class since it would be in the background. GameScreen.class, in my case, is an activity that I invoke through an Intent from MainActivity.class. And I suppose, it is because of this that the context is not set properly for Games.Achievements and it could not show the pop ups in my current activity screen.
When I added that line of code in GameScreen.class, I assume that now Games class knew where it has to popup the alerts. My explanation might sound a bit fussy here but let me know if you have any issue.

WP7: Is it possible to intercept the backstack before the journal thumbnail is created/stored

You all know the Windows Phone backstack right. If you go through some apps, tap the Home key after starting each app. Now tap and hold the Backkey to see the Backstack. You can now see some small images of your apps, and can pick which one to go to right.
Question:
Is it possible to intercept before the backstack image is created? I have tried to blur my page in various events (include OnNavigatingFrom) to no avail.
My guess is some other event (probably something we don't have access to) is triggered and a bitmap is created, because when you use the Backstack to navigate you can just see a slight transition from the saved image to a real page IMO.
Does anyone know if its possible to intercept or manipulate these images on the backstack?
Example screenshot from WP emulator of the Backstack thumbnails
Following my comment, I've just tried this:
Set a breakpoint anywhere in the code
Start the app with the debugger attached, then let it reach the breakpoint
While the execution is stopped by the debugger, long press on the back button
The task switching UI is displayed even though the managed code execution is stopped
From there, I think we can safely conclude that the task switching and the thumbnail are handled entirely by native code. Therefore, there's nothing you can do.
I recently wrote a blogpost in which I discuss the ways I tried to hide data from the application snapshot. (You can read it here: http://corstianboerman.com/trying-to-hide-crucial-data-from-an-application-snapshot/)
The outcome: You just can't hide it.

WP7 - why does click adcontrol then back button cause page backkeypress event fired on form re-entry?

I have a number of Windows Phone 7 apps, which have a main page with a custom BackKeyPress event that on the main form throws a custom exception, in order to pass testing and get to the marketplace.
These forms have an AdControl on them. For some reason, when you click on an Ad, either in testing or production, then hit the back button, the BackKeyPress event is fired on the main form.
I have code in place to handle the issue, but does anyone know why it is giving this behavior? I can understand the event firing when the back button is pressed while on the form, but why is it fired to re-enter the form?
Is this a known bug?
I have implemented code to solve this issue, but if a bug, will my workaround code for an apparent Microsoft issue either be moot or potentially harmful in the future if the bug is fixed?
Has anyone else experienced this issue?
First thing that comes to my mind here is that the main page is not releasing properly when navigating away from it.
I haven't used the MS AdControl in a few months because it is not useful for non-US developers but when I was trying it out I remember that it would hold pages in memory if you did not unregister all the event bindings
So look at shutting it down in OnNavigatingFrom and see if that helps.
I've also encountered this problem. When debugging, it looks like the OnNavigatedFrom event is never fired, so there's no tombstoning that's happening and I don't see any place in code where I can unwire that event.
I figured it out.
You have to wire up events in the Adcontrol.AdEngaged to remove the back or AdDisengaged events to readd the back event handler.

Resources