0

I searched through most answers here and all suggest we add a flag to the intent to kill old activities. The problem is my activity only receive intents from other app and has no control over it.

More specifically, my activity receive an intent to load a picture, then it uses Asynctask to load and do some complicated background processing of that picture, say, may be 2 minutes.

If the user at this moment back out (assuming that only onStop is called, not yet onDestroy) and share another picture to the app , this will start a new activity, and the previous activity cannot be accessed, but its Asynctask hold up the thread so that my new activity just freeze without starting its own Asynctask.

(I later tried the parallel thread executor, but this doesn't stop the old thread from running, thus consuming computational resources).

Any idea what I should do?

(I don't want to stop the task in onStop as this is to easy to be called. But I do want to stop the task if new picture is shared, since it is no longer needed.)

(The Asynctask will spit out a huge array of self-defined Objects declared in the main activity, and thus the activity gets immediate updates of the result from the background process, and the UI updates immediately after onPostExecute is called.)

Ivan
  • 149
  • 1
  • 12

2 Answers2

1

EDIT: It seems that your problem is that you're trying to do all this image processing work in asynctasks launched by your activity. Have you considered changing your app architecture to rely all this background processing to a service?

You can use the activity to show some UI information while you process the image in your service, or if you don't need this UI just simply communicate with the service (through broadcast, for example) to provide it the image and let the service show some information of the process through notifications.


If you don't want to keep your activity alive when you exit it you can use

android:noHistory="true" in your activity declaration at the manifest

More info here

Guillermo Merino
  • 3,197
  • 2
  • 17
  • 34
  • As metioned in the last line, I do want to keep my activity if user navigates away, unless 1) user starts a new activity by intent, or 2) System kills it. – Ivan Mar 23 '14 at 09:01
  • Sorry, I didn't understand well your question the first time, I've edited my answer – Guillermo Merino Mar 23 '14 at 09:42
  • the background process will spit out a large array of custom defined objects... is it efficient to use service to communicate these data back to the application? Right now the Asynctask uses the variables of the main activity, and thus the activity gets immediate updates of the result from the background process, and the UI updates immediately after onPostExecute is called... – Ivan Mar 23 '14 at 15:27
  • But activities are designed to work in foreground, showing a UI. What you need is a background process that does the hard work and updates the UI with the results, that's what Services do. More info about how to comunicate Activities and Services here: http://stackoverflow.com/a/22443582/1668144 – Guillermo Merino Mar 23 '14 at 15:50
  • Changing the architecture to Service seems too difficult right now. I am thinking can I do some trick like, whenever a new activity is launched, broadcast a private message, so that particular Asynctask still running in the background terminates itself when it receives the message? – Ivan Mar 24 '14 at 03:20
  • You can check this thread for more info about how to cancel an asynctask and also why asynctasks are not recommended for what you're planning to do http://stackoverflow.com/questions/2735102/ideal-way-to-cancel-an-executing-asynctask – Guillermo Merino Mar 24 '14 at 09:56
  • I have looked at that thread before. But as I explained, I am now in a new activity and have no control over the old activity. In particular, there is no way for me to call it's cancel method, nor set any flags to it... :( – Ivan Mar 24 '14 at 17:26
  • It's not a beautiful solution, but you can always keep an static reference to the latest asynctask in your activity and before starting a new one cancel the previous one if it was still running. – Guillermo Merino Mar 24 '14 at 17:30
0

This is the workaround, and seems it is working very well for the moment:

After getting a sharedpreference prefs, do this in onCreate:

prefs.edit().putBoolean("ForceClose", true).commit();

In the onPreExecute() of the AsyncTask, put:

prefs.edit().putBoolean("ForceClose", false).commit();

In the doInBackground() of the AsyncTask, constantly check for

if (prefs.getBoolean("ForceClose", false)) 
    cancel(true); 

and call finish() in onCancelled() to finish off the activity.

Ivan
  • 149
  • 1
  • 12