4

I have three async tasks, and i'd like to be able to run them synchronously. How can I do that without putting them in onPostExecute of eachother? I'm sorry if this has been covered but I can't seem to get the right key words on google or on here.

new parseZip().execute();
new loadContent().execute();
new playContent().execute();

Any help would be appreciated, or just a link to a thread

Thanks

Yash Sampat
  • 30,051
  • 12
  • 94
  • 120
Ben
  • 1,061
  • 10
  • 23
  • Your title and post are a little unclear. Do you mean you want them executed serially, or in parallel? – Mike M. Mar 05 '15 at 11:41
  • Serially, sorry if it's unclear – Ben Mar 05 '15 at 11:43
  • 1
    That's default behavior, as of Honeycomb. Check the _Order of execution_ section here: http://developer.android.com/reference/android/os/AsyncTask.html – Mike M. Mar 05 '15 at 11:48
  • 1
    Wow, it is.. Something else was causing the problem.. Thanks Mike. Assumption makes a fool of me again. – Ben Mar 05 '15 at 11:59

2 Answers2

3

i'd like to be able to run them synchronously. How can I do that without putting them in onPostExecute of eachother?

Create your own threads for the three separate tasks and synchronize them to execute serially. See here. The author of this slide has also written a book on multithreading in Android.

See also the Specifying the Code to Run on a Thread example.

As an aside, AsyncTasks are run serially by default. If I were you, I'd simply put them in the onPostExecute() of each other. What's wrong with that ?

Yash Sampat
  • 30,051
  • 12
  • 94
  • 120
  • 1
    To be honest, i've just been doing these chain calls for a while and thought they are a bit weird and wasn't the best practice so I thought i'd just come and ask.. Was just seeing if there was a solution where it would make it clearer, I guess if everyones doing it, it's fine.. – Ben Mar 05 '15 at 11:48
  • ZygoteInit, it's the default behaviour i've just found out in the comments section. sorry for wasting your time, but atleast you learnt something too :D – Ben Mar 05 '15 at 12:00
  • 1
    No need to apologize :) the concepts of programming become clear through discussion, reading and doing ... best – Yash Sampat Mar 05 '15 at 12:03
  • 1
    @Ben: You are not alone. Most modern languages have already implemented channels (go-lang) or async/await (C#, es2015-alpha), to solve this exact problem of callback hell. Chaining async calls is WRONG, your instinct is true. – Vans S Jun 17 '16 at 16:23
  • @VansS yes I have tried go lang since this question, it's very cool and I'm glad to see it. Objective c has blocks which are cool too. – Ben Jun 17 '16 at 21:48
  • @VansS: What exactly is wrong with this approach? Callback hell?! – Yash Sampat Jun 18 '16 at 06:24
1

You can query the status of an AsyncTask using getStatus(), to check if a given task has ended and then start the other task, but it would imply to check constantly for the status of wach task and this is not a good idea.

You can also, as you say, start the following task on the onPostExecute of each other, but seeing the names of your tasks I think that you are also using the tasks separately, so it would imply some kind of flag to control whether the tasks should be chained or not.

Maybe the better approach could be to create a new AsyncTask that executes al the work done by each of tour tasks (could need some refactoring to do the work in methods to avoid duplicating your code).

From the documentation:

AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework.

So, maybe in your case AsyncTaskis not the right tool to do the job and you should think about using plain Threads as @ZygoteInit proposes.

antonio
  • 18,044
  • 4
  • 45
  • 61
  • Hi Antonio, i've been told by someone that if it's doing a lot of processing like in my playContent and I need to call 'runOnUIThread' a lot, it's better to use Async Task. – Ben Mar 05 '15 at 11:49
  • Are you suggesting with the getStatus thing I loop constantly to test if it's changed? – Ben Mar 05 '15 at 11:51
  • You are right. I edited cause I am not suggesting to constantly loop to test if the status has changed (it is not a good idea). If you want to keep `AsyncTask`and benefit from its advantages without chaining them using onPostExecute, the best approach could be to integrate your existing task's doInBackground into a new one. – antonio Mar 05 '15 at 11:57
  • Antonio, it's the default behaviour i've just found out in the comments section. sorry for wasting your time, but atleast you learnt something too :D – Ben Mar 05 '15 at 12:00
  • 2
    Discussing is the way to learning, so it's never a waste of time :) – antonio Mar 05 '15 at 12:03