I have 2 async tasks (which does server requests) running just before i leave my activity.
sometimes the activity which runs this async tasks gets stuck until the async tasks finish, and sometimes the next activity shows and gets stuck until the async tasks finishes.
my question is how do i run this task in a way in which my activity's UI doesn't gets stuck (the UI is not dependable on the responses in the async tasks)
You are probably calling AsyncTask.get() somewhere in your activities code. If you call it before the task has finished executing, it will wait untill it does finish (Thus making your UI get stuck).
Can you try this.
Create a ProgressDialog set it to indeterminate and show it.
Call AsyncTask1 and in its PostExecute call AsyncTask2. Make sure you need to call this onUiThread.
In Postexecute of Asynctask2, dismiss the Progress dialog and start the next Activity.
Make sure you start your next activity on the onPostExecute() of the first Async Task. And if you have an Async task in the new activity ,call it as the last item on your onCreate Method. Following these simple rules should help
Write the code in AsyncTask doInBackground() only and call it. So that you can check whether it is accessing any UI.
eg: TestAsync extends AsyncTask...
TestAsync async = new TestAsync();
async.execute();
Try this.
Normally, AsyncTask should run in separate thread. If you create two instance. and call execute, It should execute independently. But there may be only one thread available, So it should wait(In lower version, pool size is 1.).
#TargetApi(Build.VERSION_CODES.HONEYCOMB) // API 11
void startMyTask(AsyncTask asyncTask) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
else
asyncTask.execute(params);
}
Other way is, You should run it in normal Thread.
you are must be calling 2 activities at a time in your activity
so either you must use synchronized class or function to call asynk task
or you must use singleton class to call that asynk task so that api is called in synchronized manner
as asynk task uses main ui thread to complete the task so that can be the reason that activity is getting stuck
Related
At first, this is for a step counter.
My initial structure is a service keeps logging step counter value to database.
Then a async task keeps updating the value shown to user when the app is visible to user.
I planed to create a thread to periodically call the async task.
However, after digging into the official document, "async task should be created and invoked within UI thread".
The conflict now is UI thread should not be blocked vs calling async task periodically.
Or there is else a better way to implement?
Thanks for any input.
You need to derive from AsyncTask inside your UI class (service or activity).
Inside your AsyncTask (as described here) there is doInBackground which runs asynchronously and there is onPostExecute which runs inside UI thread after your asynchronous task is over.
Just put your DB operation inside doInBackground and put something like this inside onPostExecute
MyServiceClass.this.RunNextTask();
The RunNextTask method in your UI class could use the same AsyncTask to launch the next task.
Basically title. I can run them all in a row or all at once. I need the first one to run to load data for the rest.
Any ideas?
Maybes using handler for the first one so that the code runs on a different thread and trigger the rest when that one completes:
Handler firstTask = new Handler(new Runnable() {
Run() {
//do code
//run rest of tasks
}
}
If you want to make sure that the first AsyncTask has finished and returned the required data before the rest are executed, then override the onPostExecute() method of the first AsyncTask and execute the remaining AsyncTasks inside it.
onPostExecute() is a methode called after the AsyncTask is finished, you can check for the correctness of the received data inside it before executing the other AsyncTasks also inside it.
Your AsyncTasks will be run in the order in which they are submitted and not concurrently, unless you explicitly use the ExecuteOnExecutor method. You can pass data between them accordingly.
Just to be clear, you don't have to do anything at all to make sure that the first task completes before the second (and so on) are run. Each will complete before the next is started, in submission order.
Android Asynctask Generally Understanding Questions.
If I want to make Asynctask SyncTask, how do I do that?
AsyncTask A = new AsyncTask();
AsyncTask B = new AsyncTask();
A.execute();
B.execute();
If I want A to finish before B starts how should I do that?
If I close an Activity, does the AsyncTask call on that activity gets destroy?
If I close the whole application, does the AsyncTask call on that application gets destroy?
call b.execute() in onPostExecute() of A
AsyncTask is an abstract class so you must extend it in order to add your app specific functionality to it. You implement the doInBackground() method to do what ever work is required. The AsyncTask documentation explains it in detail. I will give a brief answer to each of your question.
If I want to make Asynctask SyncTask, how do I do that?
You have the right idea with creating the async task, however as I mentioned before you have to subclass the async task to actually do some work.
Here is an example (note that the Void types do have meaning however the documentation covers them in great detail)
public class MyTask extends AsyncTask<Void, Void, Void>
{
//This method will run on the back ground thread
#Override
protected Void doInBackground(Void... params)
{
// All the heavy work should be done here e.g.
// loading from network, database etc.
return null;
}
}
Then in your activity you would create and run this task as follows :
MyTask myTask = new MyTask();
myTask.execute()
If I want A to finish before B starts how should I do that?
As the documentation states:
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.
Which means if you are using honeycomb or later async tasks will run on a single thread. So normally A should get executed before B if you execute in that order. But I would do something like this: Launch A, then when onPostExecute() of A gets called, you know that A is done, you can start your task B from this method to be sure that A finishes before B.
If I close an Activity, does the AsyncTask call on that activity gets
destroy?
The short answer to this question is No. The async task will continue to run even if the activity has called on destroy. However if the async task is tied to the activity life cycle you need to make sure you end the task when the activity dies or you will run into problems.
If I close the whole application, does the AsyncTask call on that
application gets destroy?
I am not 100% sure about this one. I believe the behavior is unspecified since now its up to Android to collect resources. It may decide to kill the task right away if its low on resources or it may not. However you should avoid this design. If you need to run something after your application has closed, then look at the Service class.
Take a look at http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html#.VNtB1LDF_38 it may help you.
I am parsing the xml file containing some names using the Async task and populating these names to the listview again via the main thread. But whats happening in my case is, when the Async task is still running, the main thread is already populating the names to the listview which is resulting in no items on the listview. Should i make the main thread wait until the Async task finish the job or is there any other way to solve this prob.? if yes how can i make the main thread wait when i don't know that how long the Async task might take to finish.?
If you want to complete the AsycTask then you can use .get() method from AsyncTask. (Which will block the MainUiThread)
But I think the best approach is without blocking MainUiThread you have to start ProgressDialog on onPreExecute() and after populating ListView in onPostExecute() of AsyncTask finish the ProgressDialog in onPostExecute().
If you have used AsyncTask, then do the xml fetch in doInBackground() and update all your UI elements of the listview inside the onPostExecute(), this runs on the main UI thread and is automatically after doInBackground(). This way you dont have to explicitly make the UI thread wait
You don't want to block your main thread and wait for the async task (this would defeat the purpose of the async task). Instead, the async task should trigger the update when it is finished in the onPostExecute method.
You may also want to have a look at the more recent Loader design.
- First of all Main thread in Android is the Dedicated UI thread.
- What you need to do is to fill the List by parsing the xml with the names and then proceed to Displaying it on the ListView.
- You can use CoundDownLatch from java.util.concurrent package to fill in the data into the list before showing it on the ListView.
- Use the method like await() and countDown() of CoundDownLatch to do this.
use AsyncTask.get() to wait until AsyncTask finish.
NOTE : this will stop execution of Main Thead until result not retrieved from AsyncTask
String str_result= new RunInBackGround().execute().get();
Log.e("","show this");
RunInBackGround is your AsyncTasc class name.
First will run async task and when it finished will show the bellow message!
I have a a service class which includes an Async task. In the doInBackground and onPostExecute I call some methods which are in the service class but outside the Async task. When these methods get called will they still be in the thread created by the Async task and therefore not interfering with the main UI.
To illustrate my lack of understanding a bit more should I try to get almost everything that the service class does into the Async task. For example the service starts up as the result of an alarm and in the onStartCommand sets a repeating alarm (this is as Reto Meire's Earthquake example)and creates a database. Would it make sense to move the code for these two operations into the onPreExecute part of the Async task?
No need to do that.. make sure that the method which you want to run in background is called from doInBavkground().. rest you can put in postExecute.... the snippet which you want to run after the backGround task should be in PostExecute(). If You call methods from doInBackground() they still run on background thread.. does't matter where they are.. and if you call it from onPostExecute() then it will run on other thread which ofcourse can make changes in your display.. just like showing dialog etc...
You should always offload as much work as possible to background threads/tasks. Something like database creation should be done in the doInBackground method. The onPreExecute and onPostExecute methods run on the UI thread and are generally used to inform the user of background activity (e.g. using a ProgressDialog).
From experience, I also suggest not using a background service if you can get away with it. If you use one, you should know how to clean it up properly since users generally get annoyed with an application running in the background.