Android background thread management and activity lifecycle-Collection of common programming errors

I have an activity in which I collect data for an online transaction. When the collection is done, I run a background thread (more specifically an AsyncTask) that calls a web-service and waits for its response, then return it to the activity. Meanwhile, a progress dialog shows up.

I want the background process to be cancelled if the application finishes or user cancels (however, I still need to notify the web-service), and retained if the activity is destroyed due to a configuration change or to free memory. I understand that I shall use onRetainNonConfigurationInstance() to detach my activity from the AsyncTask, retain it, and then reattach in the next activity, I already have the infrastructure for that. I also know that in some lifecycle callback, the isFinishing method tells me if my app is shutting down normally; and I do believe I can also handle the user cancel in the progress dialog’s callback.

I have two simple questions:

  1. Will onRetainNonConfigurationInstance() be called if my activity is killed due to low memory? (I know it will be if the reason is a configuration change.)

  2. What is the situation (as emphasized by the developer guide) in which onStop() and onDestroy() are not called? (I want to know if my code handling the cancellation would always execute.)

All in all, can I be sure that by implementing onRetainNonConfigurationInstance() and onDestroy() with isFinishing() checked, in every situation, my background thread will be handled accordingly?

BONUS question: If my application is killed for some reason (let’s say permanently), how can I provide a way for the AsyncTask to save the response anyway? Can I retain an instance of shared preferences in it and write the data in that?

  1. Will onRetainNonConfigurationInstance() be called if my activity is killed due to low memory?

    No. Your activity is never individually killed for low memory. Your whole process may be terminated due to low memory, but onRetainNonConfigurationInstance() is only designed for in-process use.

    What is the situation (as emphasized by the developer guide) in which onStop() and onDestroy() are not called?

    Your process could be terminated due to low memory conditions (onStop() is very likely to still be called, but onDestroy() might not be if Android is in a hurry, such as due to an incoming phone call). Also, your app could crash with an unhandled exception. I am not certain if onDestroy() is called if the user force-stops you, but I doubt it.

    All in all, can I be sure that by implementing onRetainNonConfigurationInstance() and onDestroy() with isFinishing() checked, in every situation, my background thread will be handled accordingly?

    “Every” is a strong word. If Android terminates your process, your thread is gone as well.

    If my application is killed for some reason (let’s say permanently), how can I provide a way for the AsyncTask to save the response anyway?

    Write the data to disk before doing anything else, and hope you are not killed before that point. Then, next time you run, notice that this saved data is floating around and arrange to do the rest of your work on it.