How to execute parallel REST API calls in android - android

Hi I am developing android application. My application contains REST API calls for fetching data from server. So my application requirements are like this:
consider I have 2 REST API calls all are independent; That mean both are not dependent on each other; So I want parallel execution. Result of both API calls associated with two different activities.
I want to run both network calls in background. Don't want to execute on UI thread.
I am confuse with following few solutions:
use separate async task for each network call. What happen if I execute 10 calls parallel with async task?
Use intent service: Will intent service is good solution for handling multiple network calls parallel in background.
How to handle this in proper way. Need good solution for this. Need help. Thank you.

Executing on 2 AsyncTasks will work. However, on Android versions 3.0 or higher you need to call task.executeOnExecutor(THREAD_POOL_EXECUTOR, params) instead of execute. If you don't do that, the 3.0 implementation of AsyncTask only runs 1 task at a time serially. If you do this it uses a pool of about 5 threads to run them.

Related

Can we chain multiple API calls or keep track of multiple calls being made at once?

I have 21 API calls that need to be made once the app gets to the splash screen. What my app does is as follows:
a> Make API call using retrofit's enqueue method.
b> once the response is available(call success) it stores data to local database using greendao. Inside app it only uses data from greendao databases. What I need is to keep track of the api call whether it failed or not. If failed retry. Also if there is a way to chain the requests can anyone mention them? I looked into rxjava which allows chaining upto 2 or 3 apis (as far as I know). Any help is much appreciated.
You can create IntentService which will run call.execute() code one by one.
This way you will call synchronous call to all apis.
Once all request completes send broadcast to activity or communicate with activity through other mechanism.

Multiple AsyncTask vs multiple requests within one AsyncTask

I'm following this tutorial to create an XML reader with options to download multiple feeds at once. Are there any downsides to executing multiple AsyncTasks (max 3) simultaneously? I'm going to add a timer to check if they finished.
Running multiple AsyncTasks at the same time -- not possible? It is possible. However it could be, that due to the cpu depending on each device, one is faster than the other. But as #Alex already answered, you wont get "real" multitasking. Haven't it tried yet I would assume, that doing it all in one AsyncTask is faster. And you could reuse the connection you established to the server.
For better architecture I'll choose 1 AsyncTask per request. It is easier to manage actual request. Also it would be easier to modify (add/remove request).
Downsides of executing multiple AsyncTasks depend on your knowledge of AsyncTask lifecycle. You need to execute it correctly (depends on android version).
Good article about the dark side of Async tasks http://bon-app-etit.blogspot.com.by/2013/04/the-dark-side-of-asynctask.html
They won't be run simultaneously, but serially. See 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

Android: Future/FutureTask for parallel processing of data

I am trying to optimize a complex data updater and parser for my Android app. The server provides three interface functions. The parser requires the data from all those three functions.
When the download of the data is finished, the parser can start. It consists of many different independent tasks which can be parallelized.
I was thinking of using Futures or FutureTasks for processing the data.
So basically, this is the procedure:
create Task-1, Task-2, Task-3 for downloading the data
wait for the downloads to be finished
create Task-1,..., Task-N for parsing the data
wait for the parser to be finished
call a callback to signal that process is done.
My first question: is it possible to create Futures with asynchronous functions, which use callbacks to return the data (network framework)?
Second question: are there any drawbacks in using Futures or FutureTasks respectively in this scenario or are there any better solutions to achieve that?
Thank you.
Basically you are Trying to achieve the following.
Step 1 - User from UI starts 1,2,... n download tasks.
Step 2 - Once each of the task is completed, new thread should be started to process it.
Step 3 - Once all n Tasks are completed, UI should be updated ... may be with a success dialog.
This can be achieved easily by using Async Task. I am going to tell you the approach and not the code sample.
Things to note about Async Task
Before 1.6, Async Task handles all background operations with a single additional thread.
After 1.6 till 3.0 .. it was changed, so that a pool of thread had begun to be used. And operations could be processed simultaneously.
Since Honeycomb default behavior is switched back to use of a single worker thread (one by one processing).
How to implement your requirement
For your requirement, you can use the method (executeOnExecutor) to run simultaneous tasks (1 till n tasks) if you wish (there two different standard executors: SERIAL_EXECUTOR and THREAD_POOL_EXECUTOR).
The way how tasks are enqueued also depends on what executor you use. In case of a parallel one you are restricted with a limit of 10 (new LinkedBlockingQueue(10)). In case of a serial one you are not limited (new ArrayDeque()).
So the way your tasks are processed depends on how you run them and what SDK version you run them on. As for thread limits, we are not guaranteed with any, yet looking at the ICS source code we can say that number of threads in the pool can vary in range 5..128.
When you start too many tasks (like 100s or more) with default execute method serial executor is used. Since tasks that cannot be processed immediately are enqueued you get OutOfMemoryError (thousands of tasks are added to the array backed queue).
Exact number of tasks you can start at once depends on the memory class of the device you are running on and, again, on executor you use.
So by following this approach, once all the tasks are completed, you can use a handler to update the UI.
Hope this helps.

Should I use a thread or service to run tasks in the background in Android?

I'm building an Android library to collect data from the host app and send this data to an online server in the background. I realize that this would require some sort of multi-threading/use of a service/forking.
The application simply keeps adding data through library calls, and the library should handle the sending of this data in the background without disturbing the main UI.
How should I got about making this library? Should the entire library run on an Android Service? Should I just use another thread? This is my first foray into parallelism. I'm not sure what the best way to do this is.
A detailed response is appreciated.
Some of the answers aren't quite correct. Services (Android Service component) are NOT made to run in the background, they run in the default UI thread.
In all honesty, the question shouldn't be service or thread or anything. Your library does NOT need to kick start a service, it could simply be a class (singleton/static, whatever it is) that should extend AsyncTask (or anything else running in the background that I'll explain in a bit) and use the doInBackground method to send stuff to the server. Note AsyncTask is nothing but a Thread internally. So here's what I would do:
Let's call your library's main class that interfaces with your server ServerHelper. You can make this a singleton (or static but that's a separate discussion). Within this class create an innerclass say ServerHelperCommandTask and extend AsyncTask. You really should review AsyncTask in detail to understand how that works. Because you would be asked to override doInBackGround. Anything you put in this method will autmoatically get exectued in a separate thread off the UI. Then a callback is invoked called onPostExecute that you can override as you will get the result from doInBackground here. This OnPostExecute is called in the mainThread so you can check for say error results here, etc etc.
This would be the simplest method; however, there are many other methods and libraries that help you with networking and deal with all the background stuff internally. Google just release a library called Volley which you may be able to plugin and use as it would do all the parallel processing for you. But that may take a bit of learning curve. Hope you understand AsyncTasks as in your case if the data pushed isn't a lot, then AsyncTasks is the way to go. Also note that you can call multiple AsyncTasks but while that seems on the surface that it is kicking off multiple parallel threads, that isn't quite accurate since honeycomb as internally you can call 5 Asynctasks but all 5 of those tasks will be executed sequentially so you wouldn't have to worry much about serializing.
Service would be a more reliable solution for situation You described.
I mean running background threads from service, not from Activity. Service itself does not provide separate thread by default, by the way.
The point is that Services have higher priority than acitivities so they will be destroyed with less probabilty, so your long-running task won't be interrupted.
You could do both but here's pros and cons for each solution :
Services are made to run in the background, even when your app is not in the foreground. sers usually don't like having services running for nothing.
From your description it seems that you would only need to have this thread running when the app is in foreground right ?
If so, a normal thread could do the job.
However, a service might be easier to implement.
Hope it helps
You should definitely use a Service in this situation. Async tasks and manually creating a thread is not really suitable for computations that need to run in the background for network communication. Use the Async task for long running local computations (e.g. for an algorithm doing sorting).
Note that if you use a service, it will by nature NOT run as a background thread! You need to handle threading manually. In order to save yourself from this hassle (especially if it is your first time with multi-threading) use an IntentService!
The IntentService may be invoked using the startService method as with any other service, but the IntentService class is able to handle multiple invocations as in a producer/consumer pattern. This means that you can queue commands automatically to the service just using the startService method. In the IntentService class that you make, you can then handle different types of commands by looking at the given action inside of the intent that is sent along as a parameter in the startService method.
Here is an example of how the implementation of an IntentService:
public class SimpleIntentService extends IntentService {
public SimpleIntentService() {
super("SimpleIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
String commnad = intent.getAction();
//handle your command here and execute your desired code depending on this command
}
}

Download queue in Android

What's the best way to implement a download queue in Android?
I suspect there might be some platform classes that might do most of the work.
What's the best way to implement a download queue in Android?
Use an IntentService. It supplies the queue and the background thread for you, so all you have to do is put your download logic in onHandleIntent(). See here for a sample project demonstrating this.
I would suggest looking at the java.util.concurrent package and more specifically read up on Executors
You can create an ExecutorService which would only run 'n' number of Runnable objects at a time and would automatically queue up the rest of the tasks. Once one of the threads being executed finishes execution it picks up the next Runnable object in queue for execution.
Using an IntentService will make it quite difficult to support cancellation. It's just something you need to be aware of. If you can, it's API Level 9, you will be better of using http://developer.android.com/reference/android/app/DownloadManager.html
From API 11 up, a good approach is to use a FixedThreadPool with async tasks. Do once:
ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
Where 3 is the number of downloads you want to run at the same time. It will queueu the task if there are already 3 downloads running, and automatically handle the task later.
Launch your async tasks with:
yourAsynTask.executeOnExecutor(threadPoolExecutor, params);
Params is probably the url you wish to connect to. You can read it out in the onPostExecute of your asynctask, and connect to the server using a HttpURLConnection.
Make sure you call down this on shutdown:
threadPoolExecutor.shutdown()

Categories

Resources