0

First of all, sorry for by bad English. I have android 2.3, so there is "Real" parallel AsyncTask instead of sequentially execution (android 3.0 and higher). I have several AsyncTasks, each of them executes onPostExecute() callback (I know that it will be executed in UI thread). Suppose I have only 2 parallel AsyncTask, and when first task has finished its job, callback onPostExecute() will be called. Is it possible, that while onPostExecute() (from first AsyncTask) method is running on UI thread, second task is calling its onPostExecute() method interrupting current execution of first AsyncTask's onPostExecute() ?

// UPDATED I explain it with code now:

// AsyncTask1
onPostExecute(Result result) {
    activity->processResult1(result);
} 

// AsyncTask2
onPostExecute(Result result) {
    activity->processResult2(result);

Suppose AsyncTask1 has finished its job and that processResult1() is very long running method: While we executing processResult1() on UI thread, AsyncTask2 finish its job. What happens now?

  1. processResult1() will be interrupted by processResult2()
  2. processResult2() waits till processResult1() ends

3 Answers3

2

When AsyncTask finishes it's doInBackground method, it posts Runnable (which executes our onPostExecute method) to UI thread. By "post", I mean that there is some kind of Runnable queue, which means that those methods (onPostExecute) will be executed in serial way (one after another). So, one onPostExecute method can't interrupt another (if it was already posted into UI thread, of course).

Dmitry Zaytsev
  • 23,650
  • 14
  • 92
  • 146
1

First "so there is "Real" " is wrong. So called "real" async taks are available on higher versions of android without much trickery, you just need to invoke it different way as default one has changed.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • Yep, I know that they are available on higher versions. I am just talking about default behavior. – Cyrus Smith Jul 05 '13 at 13:07
  • I found this in android docs: "AsyncTask guarantees that all callback calls are synchronized in such a way that the following operations are safe without explicit synchronizations." Does this mean that one onPostExecute() can't be interrupted by other onPostExecute() ? (Yes, I know that it can be interrupted by other task, such as event processing) – Cyrus Smith Jul 05 '13 at 13:10
  • @CyrusSmith, yes. That would be my interpretation as well. Marcin is correct. – William Morrison Jul 06 '13 at 05:35
  • I asked actually about that: if one thread required a submission to runOnUiThread (in this moment we have a method executing on UIThread), will it wait till method ends, or it will just interrupt executing to do its job? Your note (http://stackoverflow.com/questions/17499435/) - "... Even then, if it required a submission to runOnUiThread, it would likely fail as a long running operation is in progress.", makes me think that onPostExecute() method cannot be interrupted by other onPostExecute() method, unitl job is ends – Cyrus Smith Jul 06 '13 at 05:47
  • @William Morrison, if it is correct, that one onPostExecute() method cannot be interrupted by other, why Marcin Orlowski answer is correct too? – Cyrus Smith Jul 07 '13 at 05:14
  • He probably meant "not correct". But I am unable to peek AsyncTask sources at the moment. – Marcin Orlowski Jul 07 '13 at 09:10
  • @William Morrison, Marcin Orlowski, I am in misunderstanding now, who is correct... I add some code in question. – Cyrus Smith Jul 07 '13 at 17:04
0

Read this: (copied from android docs here):

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.

If you execute several AsyncTasks, they will run simultaneously if the device is DONUT<= device api < HONEYCOMB. This is because android uses multiple background threads to execute AsyncTasks in these versions rather than a single thread. As a consequence, I would assume tasks would not necessarily be executed on the GUI thread in the order they were started, as they'd be executing simultaneously. But this is an educated guess, I do no know this for sure.

If your device software is < DONUT or >= HONEYCOMB, operations will be posted to the GUI thread in the order they were started. This is because on those versions all AsyncTasks will be executed on one background thread, so they won't be executed independently.

Now for the part I think you're asking about:

In all versions its possible to cancel one AsyncTask from another. However, in versions >=DONUT and < HONEYCOMB, tasks you try to interrupt may have already completed as AsyncTasks will be executed simultaneously.

It is not possible however, for two tasks to execute on the GUI thread simultaneously as it is one thread. One AyncTask could throw a flag to prevent some other AsyncTask from performing its GUI update once completed, but as tasks should be short lived on the GUI thread this would be a bad approach.

Community
  • 1
  • 1
William Morrison
  • 10,953
  • 2
  • 31
  • 48