By default, multiple instances of an AsyncTask object will run in serial. That's hardly making the most of Android's capabilities and can make your app less efficient. Configuring the instances to run in parallel in such situations involves only a minor code change, though you'll need to check that you've set things up correctly to avoid conflicts. Learn more about executing multiple tasks in parallel in Android apps with RESTful in this online video.
- View Offline
If you create more than one instance of an async task object and execute them all at the same time, by default they'll run serially. That is, one will have to complete before the next one picks up and starts its task. But you can change this behavior. I'm going to demonstrate the default behavior with this project, Parallel Tasks. It picks up where the last project left off. When I run the app in the emulator and click the action bar item, I see the first task running.
Now watch what happens if I click the action bar item more than once quickly. I'll click it once, and click it again. I immediately see starting task displayed. That happens right away, but the second task doesn't start the background work until the first task is complete. So that's called Serial Processing. Here's how you can change to parallel processing if you want to execute more than one task at the same time. If, for example, you want to work with more than one HTTP request simultaneously.
It’s actually just a minor difference in the code. When you call your MyTask object execute method, you’re passing in something called an executor. And the default executor works serially. To use a different executor, call a method named execute on executor, and you'll pass in the name of an executor class that you want to use. The first argument is now the executor class. For parallel processing. Pass in AysncTask.THEAD_POOL_EXECUTOR. Notice that there's a SERIAL_EXECUTOR. That's the default. And we're changing to THREAD_POOL. That's for parallel. Now, I'll clean up this code and separate the first argument from all the others.
And now I'm still passing in my three parameters but they've been pushed over a bit. The first parameter is in the second position. The second parameter in the third position and so on. I'll save that change and run the app. And now, watch the change in behavior. I'll click Do Task once and then twice and then three times. And notice how the different parameter executions are all mixed up together now. I see param two and param two right next to each other. And param three and param three right next to each other. But also notice that something interesting is happening with the user interface management. To show this clearly I'll exit the app. And then restart it. Watch the progress bar. I'll click Do Task once, then three more times. The progress bar turns invisible after the first task is finished executing, even though all the other tasks are still running. This turns out to be a problem with my own app logic. Not something intrinsic to the AsyncTask class. Let's take a look at the code I'm using to control the visibility of the progress bar widget. When the app starts up in the onCreate method, I'm making it invisible. Then in the AsyncTasks on PreExecute method. I'm making it visible and in on post execute I'm making it invisible again. But I don't have any logic to find out if this is the last task that's finishing. I'm just assuming that there was only one task. So there are a few different ways to solve this. But I'll show you a simple pattern, using a Java list. I'll go to the top of my activity, and I'll create a list object. This is a standard list for from Java.util. The list wants to know what type of items it will contain, and I'll pass in my task. And I'll set this variable name to tasks. Now I'll instantiate this list, in my on create method. I'll place the cursor after the existing code, and I'll say tasks equals new ArrayList. Notice when I autocomplete the code, that the type of the items in the list is re-declared. If this happens in your version of Eclipse, it's because your project is configured to use Java 6 code compliance. I'll show you how to fix that, and use Java 7 code style.
I'll go to my Project Properties, to Java compiler. And before you make this change, make sure that you have used default compliance setting selected. And then change from Java 1.6. To 1.7. Click OK and then Yes. And then you should be able to delete the redeclaration of the generic type and save and this is Java 7 style syntax which now works fine in Android. Okay. So far so good. I have a list where I can store references. To all of my tasks. I'll go back down to my onPreExecute method. In onPreExecute, I'm going to wrap this bit of code for I'm setting the visibility of the progress bar to visible, with a little check. Above that code, I'll use an if statement, and I'll set the condition to if task.size has a value of zero. And I'll move this code that's setting the progress bar to be visible. To within the if clause. So now I am only changing the visibility if there are no existing tasks. Then, I'll add the current task to the list. With tasks.add and I'll pass in this which references the current task object. Now, I'll make a copy of that code. And I'll move down to on post execute. I'll paste that code in, and I'll change the logic here so that first i'll remove the current task from the list. I"ll get rid of the code that setting the progress bar to visible. And I'll move the code that's setting it invisible to within the conditional block. Now, the code is saying remove the reference from the current task to the list, and then check the size. And if there are no remaining tasks, then make the progress bar invisible. And, now my logic is correct. I can now run the app and execute multiple parallel tasks again, but this time the progress bar will stay visible as long as there's at least one executing task.
I'll click once, then twice and three times. And watch the progress bar, it should only disappear once the final task is complete. So working with multiple parallel tasks requires just a bit of code to actually make the tasks parallel but it might require some additional application logic. To properly manage the user interface and any progress reporting that you might be doing to the user.
- Working with background threads
- Defining background tasks
- Requesting content with HTTP requests
- Parsing web service responses
- Downloading data, including images
- Sending HTTP parameters to the server
- Using higher-level client libraries like Volley and OkHttp
- Managing an app's networking abilities