Calling Asynctask in a queue - android

I am working on an app and want to send some data to server. I was able to send the data to server when the updates that I was sending to server were periodic.
But now Its upon user interaction. I have to send 1 or more calls to server. I cant skip and omit any call towards server. Just suppose the following case:
Case:
Let say I have a button on its click I launch a asyntask that put some data on server and let suppose it takes 5 to 6 seconds. But I want to trigger multiple asyntask , if user press the button multiple time. Let suppose he presses the button 7 time in a row. so the 7 AsyncTask must run in a queue one after an other.
I have heard about schedular and all others but I am unable to understand how to work with them using asynctask as well.
Possible solution : I can disable button until and unless first Async task is not completed, But I really do not want to do it, because under the requirements and needs I have to call async task as many times as user presses the button.
please help me, any source code will be appreciated.
Note: With asynctask I have nothing to update the UI.
Update :
under my need I want to queue the asynctask with specific data and it must automatically run when the previous task is completed and if user exit the application it should continue running until and unless it completes the execution of all queued asynctask.

Let suppose he presses the button 7 time in a row. so the 7 AsyncTask must run in a queue one after an other.
Depending on what API your app target you may simply need to do nothing special. Official documentation reads:
Order of execution
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
therefore starting from Android 3.0 execute() is all you need really, which means unless you support ancient versions of the platform you should be seeing serial execution by default.
Alternatively, you can drop AsyncTask in favor of IntentService which are executed one after another.

Related

Is there any point in using Asynctasks for api calls that require a response to proceed?

I feel that the answer to this question is too obvious, but part of me still wants to ask it anyway.
I am creating an Android app that makes several HTTP POST/GET requests using APIs when the app is launched for the first time by the user. All these requests are made by launching Asynctasks within the activity.
For example, there is an activity where athe user has to select an item from a list retrieved from the API. After he selects one, a progress bar is displayed to the user while the app sends the selection to the API to retrieve another list, and in the next activity, the user selects items from this list. Clearly, the user can't go this second list until a response has been received from the server after the app sends it the first list's selection.
In such a case, is there any point in using an Asynctask to send the selection of the first list, since the user is prevented from doing anything (by being shown a progress bar) until a response is received and the next activity is started. Wouldn't it make the code less complex if I just made the API call on the main thread?
I hope this wasn't too confusing.
Thanks
I got your doubt completely. Good question. The root cause of the doubt because you are thinking you don't need to interact with the app till the process completes. But you actually want to. Event the progress bar will freeze if you could do something like it.
Ok, let's just assume you don't even have a ProgressBar. However, handling the different UI components such as Spinners, EditTexts is not the only duty of the main thread. It should define different callbacks in the activity lifecycle. Doing big tasks in main thread will also freeze callbacks like onPause(), onStop() etc. That is why the 'NetworkOnMainThreadException' is being thew.
Basically you cannot call the api on main thread as it will block the UI. Also now Android does not allow it to happen and throws 'NetworkOnMainThread Exception'. Its fine to use Asynctask for any task that takes few seconds and you get the callback in it , which in your case is required before you proceed to next screen.
Best way to do it is by using Networking libraries:
Refer this
https://developer.android.com/training/volley/simple.html
First of all you cannot do netwok call on main thread, it will raise NetworkOnMainThreadException , You can still by pass this exception by adding the couple of following lines in your activity
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
but it is always recommended to perform network operation in background,
else it may cause your app to stop responding, and can result in the OS killing your app for being badly behaved , go through this article once link
Any operation that takes more than a few seconds to perform should be added in a separate thread. All network operations should be performed on AsyncTask or do have a look at RxJava and RxAndroid. To be specific to your operation, any UI Operations during a network call can be performed in onPostExecute. If you're working with thread class then use a Handler.
As others mentioned, if main thread is used for network operation, it would make your app unresponsive.
User may want to start a different flow in your app by starting an activity from menu or action bar whatever is available in your app to start other flow.

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.

Multiple async tasks not executing properly

I am trying to start 6 async tasks at a time in onCreate() of the activity. But I noticed following:
a) If I stay on same activity all the async tasks' doInBackground() execute properly.
b) If I switch to some other activity, only 4 or 5 async tasks' doInBackground() executes. Last async task's doInBackground() never executes.
Can someone tell what I might be doing wrong. I am staring different asynctasks in a for loop. If I do this in onStart(), then all the async tasks are executed again if I switch to this activity. Please help.
Here is the sample code:
For(int i=0;i<7;i++){
webServiceTask= WebServiceTask.getInstance();
webServiceTask.execute("");
}
Maybe you should consider some of the following points:
Is the WebServiceTask retrieving any information that is worth persisting (i.e. not very volatile, with a high risk of the user requesting the same data over and over again): in that case you can offload your work to an (Intent)Service and communicate the result back to your app via a ResultReceiver, or a ContentProvider (just to name a few).
AsyncTasks are not guaranteed to run to completion if no Activity or Service is around to keep your app's process alive.
If it is ok that the WebServiceTasks run after eachother, then you can probably also change your code to use only one AsyncTask that sequentially performs those tasks. You can even consider implementing AsyncTask's progress reporting mechanism.
If the operations performed by the AsyncTask(s) have no meaning once the Activity is closed, be sure to .cancel() them in your onStop() or onPause() lifecycle methods.
Keep bullet 3 of Ed Rowland's answer in mind, which I also posted in my earlier comment to your question.
Happy coding!
You need a Service of some kind to keep your process alive after the user switches away. Once your activity loses focus, Android is free to shut down your process altogether. Or your Activity. Either will cause problems, particularly if you are using the context of an Activity that has been shut down.
The Right Thing to Do (tm) is to implement a Service, and pass the operations off to the service for execution.
There are any of a bunch of reasons why only four tasks are running concurrently. Off the top of my head:
HttpConnection pools connections to servers, and throttles the
maximum number of connetions to any given server to some reasonable
value. 4 sounds about right.
your target server is throttling the number of simultaneous connections.
Your thread pool isn't as large as you think it is. Starting an API 16 (I think) the default threadpool size is one thread! (!!) Rationale: apparently Android OS developers got fed up with Android app developers doing threading wrong. Is it possible your tasks are executing serially? That would more or less fit the symptoms you describe.
But that's kind of a separate issue.

AsyncTask issue

In my app there r 6-9 AsyncTask they get fired by onlick event ,but after 5 Asynctask other asynctask doesnot run in 2.1 emulator.on DDMS Thread view I can see all 5 AsyncTask are on waiting status hence other asycntask dosent.
Any help would apprecited .Thanks in advance.
By default in most versions of Android, only 5 threads are spawned to process AsyncTasks unless the queue is full. This is fine though as hopefully you're not counting on these AsyncTasks to be processed in any sort of order, any of the others will get processed once any of the first 5 are done.
Try to lauch one after another, or do you want all of them to be executed at once, i fear that as i remember that atmost 5 task can run simultaneously, though i the latest api i think this also has changed.
THANKS

Android Asynk Task

is a good practice to have an Asynk task with a loop like this inside?
while (true) {
check queue and request API
Because i need to wait for my Activities and service needs to comunicate with the APi.
Thanks
I am assuming the "queue" is a Java queue, perhaps a LinkedBlockingQueue. If so, that queue is unnecessary, as AsyncTask has a queue to go along with its thread pool.
So, the question is: what triggers things to go in the queue?
If the trigger is a user event (e.g., menu choice, button push), just have it launch an AsyncTask, or have it have a Service launch an AsyncTask. That work will be queued up by the AsyncTask system.
If the trigger is the passage of time (e.g., we want to check an external server every 10 minutes), I would use AlarmManager and consider switching from AsyncTask and a Service to using an IntentService.
I have a priority queue in order to select first the important calls to the API.
My program have two services:
One calls the API when a message is added to the queue. The call to the api is made by an Asinc Task in this way:
messages.add(request);
new DownloadApiTask().execute();
The other service is updating the local database. For that, i have a loop in which i call the first service in order to get data from the API. The basic structure is:
while ihave data to updload
mFirstService.putMessage(request).
Fine, the problem is i have a rejected Execution Exception every X calls, I think it can be because i invoke the asinc task every time i take a message.
For that, i was thinking in force to the asinck task to check the queue instead executing it.
I hope you can understand my problem.
Thanks

Categories

Resources