Xamarin.Mobile: task-based API marked as obsolete - android

The latest release of Xamarin.Mobile component obsoletes some Task-based APIs for Android. Release notes briefly comment on this:
Given the fragility of the Task<> based API on Android due to Activity lifecycle realities, the async API is now marked [Obsolete] specifically for Android.
Could someone please explain what fragility is meant here?

Essentially, using Task across app lifecycle boundaries is asking for trouble. When the camera Activity starts on Android, you are actually starting a completely new app. Your app is no longer running in the foreground, so Android is completely within its rights to kill off your app and just restart it when the camera returns. If this happens, your Task instance has been destroyed and so any awaits or ContinueWiths you have will never execute. It's not a Task/Android issue, it was simply a design flaw in Xamarin.Mobile.
As a result, the magic API was deprecated in favor of one that utilizes OnActivityResult, as it is the only way to properly handle this situation. If you notice, the new API GetMediaFileExtraAsync still returns a Task<MediaFile>.
(Source: I wrote Xamarin.Mobile).

Related

WorkManager instances keep alive even after the app is uninstalled (?)

I've been trying out the new Android WorkManager API and it seems to work fine. However I noticed something while testing my app: before creating a new periodic worker instance, I check for status to avoid creating more than one:
WorkManager.getInstance().getStatusesByTag(myTag)
.observe(lifecycleOwner, Observer { status ->
// creates a new worker if status returns nothing
})
The first time app launched the status returned nothing and a new one was created, but then I needed to uninstall my app and when it launched again there was already a worker created, from the logs:
WorkStatus{mId='UUID', mState=ENQUEUED, mOutputData=androidx.work.Data#0, mTags=[tag, tagName]}]
I know the API is still in alpha, but I was wondering if this is expected and if this won't be a problem. I think that if user uninstalls your app these background tasks should be removed too. I've been trying to find some information related to this, but I couldn't so far.
Has anyone seen this or can anyone point me a documentation or something similar?
Thank you for your help
Of course NOT. Once you uninstall the app there will be no instance of WorkManager.
WorkManager API will work even if your app is process has been killed but not after uninstallation of app. WorkManager API implementation is part of your Application but not Android OS.
Please check your uninstallation again.

Quit application when there is a new update android

I was wondering which approach is best for forcing users to update my android application.
Should I just ask my server if there is a new version in the main activity and if there is just prompt a message and call System.exit(0); or is there is a nicer approach to this? Is it possible to check the playstore for new update? Or is this behavior of forcing update a bad practice? even if the update is important (that would make some features not work in old versions)?
Thanks
Generally, it is best to respect the user's choices. In Android, users can choose whether or not to enable automatic updates (and whether or not to update at all).
That being said, you wouldn't be the first developer to implement this functionality. If you do go this route, I would recommend calling finish() on your Activities instead of calling System.exit(0); to ensure that everything goes through the Activity lifecycle properly.
There is some great discussion about quitting an application in general at Quitting an application - is that frowned upon?.
Another alternative to forcing users to update your application when your application relies on a remote server (such as a PHP backend) is to provide backwards compatibility when you update the backend. You don't necessarily need to provide backwards compatibility indefinitely, but providing at least a few versions of support is probably a good idea.

Fragments, setRetainInstance(true), and threaded libraries

Here, Dianne says that the old methods of retaining objects via onRetainNonConfigurationInstance() are now made obsolete by the fact that you can retain Fragment instances over configuration changes.
And here, in the API Demos for fragments, it shows how to use this method for maintaining threads after a configuration change.
I see that during a configuration change, when the Fragment might not be attached to any activity and the thread is done doing it's work, it's able to call wait() so that it doesn't try to deliver results while an Activity isn't attached. I find this very useful, and a great way to mitigate one of the more pain-in-the-butt problems with Android orientation changes.
However, if you're using a threaded library (an API library that uses a thread executor, for example), where you don't have access to wait() on said threads, how could we use this new feature to our advantage?
How can we ensure that messages won't be delivered while an activity is not attached?
I've been thinking of a way to maybe queue up messages and delivery them when a new Activity is attached, but I wanted to hit up you guys and see if you've already come up with some solutions.
Also, note, I've looked into the LoaderManager API, and it seems like it would be good for data that needs to be loaded when an Activity is shown, but not for something event based, like logging in via a button, etc.
You could get around this issue using a higher level concurrency utility such as a Latch, which you could have all of your threads wait on until the new Activity is attached (just before they try to access the message queue to deliver their result).
Once the Activity is attached, you can release the Latch, allowing all the threads to deliver their results.

Android Force Close Uncatchable Unreportable

I've released my second game project on the Android Market this week, and immediately had multiple 1-star reports due to force closes. I tested it on many handsets and many emulators with zero issues. I'm completely at a loss for how to proceed and looking for advice.
I use Thread.setDefaultUncaughtExceptionHandler to intercept and report uncaught exceptions, then close gracefully. The people reporting force closes aren't getting to any of that, even though it is the first thing set in the application's main task constructor, and everything is wrapped in try/catches throughout. They are also reporting that there is no "Send Report" option in the force close popup (providing the Developer Console error reports), so I have absolutely no way of knowing what the problem is.
Uses Android 2.0, with android:minSdkVersion="5". Only Permission required is INTERNET.
(on Android market as 'Fortunes of War FREE' if you want to test)
I'm a bit surprised about the missing "Send report" button. What API level did you build the game with? I usually build the level with your minimum API level to make sure you're not using any API calls beyond that, but then switch back to the highest API level so you can use functionality like "install to SD".
I'm sure there's at least one user who wrote you a mail. Can you ask them to install LogCollector and mail you the log?
Btw, in general, I wouldn't use Thread.setDefaultUncaughtExceptionHandler so there IS the option to send a report. (It's ominously missing in your case, but normally, it should be there.)
Btw btw, the exception handler applies to the current thread. If you have an OpenGL app, maybe the crash happens in the GL thread?
I'm not sure if I understood you correctly, but as far as I know Android only shows that report dialog if you use its default UncaughtExceptionHandler.
Try this:
In your UncaughtExceptionHander's constructor, call Thread.getDefaultUncaughtExceptionHandler and save the returned object in a variable (let's call it defaultHandler). In your Handler's uncaughtException() do the things you want to do, and then call defaultHandler.uncaughtException() afterwards.
Maybe something you should know:
In my experience, your Context isn't functional anymore at uncaughtException(). So, you can't send broadcasts, etc anymore.
By the way, if you really wrapped everything in try/catch, that could be the reason why error reporting doesn't work as expected? :P
Good luck
Tom
Perhaps the force closes are caused by stalls, rather than exceptions. Users may not notice the difference. This kind of problem can occur more often if users have CPU hogging services running at the same time as your application, which explains why you're not seeing the issue in your testing.
Permission Internet sounds a lot like you try to transfer data from the net, which is very fast in your local LAN, but all of a sudden becomes slow (and time consuming) when people try this over their GSM connections.
If you then do the data transfer in the UI thread, this one is blocked and the system detects the block - but then this should end up in a "Did not respond" -- but then I've seen one user report an error with in the market on my app that was such a slow down cause.

Android 2.2 deprecates restartPackage but adds another headache

Android 2.2 release notes have just been released. ActivityManager.restartPackage method has been deprecated and the description is:
the previous behavior here is no longer available to applications because it allows them to break other applications by removing their alarms, stopping their services, etc.
Instead 2.2 has given another tool for pesky "task killer" apps by introducing new ActivityManager.killBackgroundProcesses method.
More Info
Can someone explain whether ActivityManager.killBackgroundProcesses will kill our scheduled alarms?
If so, deprecating ActivityManager.restartPackage was pointless as "task killer" will now abuse ActivityManager.killBackgroundProcesses.
I have made tests with this new killing method : alarms are not killed. services are restarting.
It also appears from my testing that user-visible activities are not closed when this method is called.

Categories

Resources