2

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?

Vincent
  • 1,027
  • 1
  • 11
  • 20

1 Answers1

3

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.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thaks, I was hoping you will be the one answering! So I have no chance making another web-service call upon isCancelled() is detected when my process is terminated due to low memory, and I can only hope that I will have enough time to write the data (still, can I use shared preferences for this or it's also being destroyed and thus not advised?). I guess I can cancel the background thread before calling finish, and onReatinNonConfigurationInstance() is enough to handle configuration changes. – Vincent Jan 28 '12 at 14:25
  • @Vincent: "can I use shared preferences for this or it's also being destroyed and thus not advised?" -- values in `SharedPreferences` are not "destroyed" until the app is uninstalled. That being said, `SharedPreferences` are only incrementally better than using some other sort of file. If you are using a database for other stuff, I'd consider storing your information there, simply because it is transactional. – CommonsWare Jan 28 '12 at 14:27
  • I didn't mean the storage, but the object I have to use to write it. As far as I can guess, it is linked to the current application. I don't use a database yet, since only a very small amount of temporary data is stored. However, I will consider the idea, transactonality sounds pretty good. Thank you for your answers! – Vincent Jan 28 '12 at 15:14