I am doing data fetch from net in an external task.
Now this fetch happens in two steps. So I want to display some message after the first step.
This will happen in the async task not on the UI task.
On the main UI task I already have a progress bar in the preexecute method.
I would like to know if there is a way to display something from the background async task.
I saw handle to be used for threads. Do we have something similar for async task?
AsyncTask has an onProgressUpdate method which runs on the UI thread. Couldn't you use that somehow?
You have to Override the onProgressUpate Method of your AsyncTask. There you can do the stuff to Display the Text.
To trigger onProgressUpdate you have to call publishProgress() in your doInBackground-Method.
Related
why should we use onProgressUpdate() method in Asynctask class,
i am using onPreExecute() and onPostExecute() along with doInBackground() but never used onProgressUpdate,In which cases we will use this method.
Thanks in Advance for your response.
onProgressUpdate(Progress...), invoked on the UI thread after a call
to publishProgress(Progress...). The timing of the execution is
undefined. This method is used to display any form of progress in the
user interface while the background computation is still executing.
For instance, it can be used to animate a progress bar or show logs in
a text field.
As you read, you can publish your async task progress by using this.
protected void onProgressUpdate(Integer... progress) {
showProgressPercent(progress[0]);//write your own codes
}
Source
onProgressUpdate() is used to better the user experience by updating the user about the background process initiated at some time. For more information, refer to the docs.
AsyncTask lifecycle : onPreExecute -> doInBackground -> onPostExecute
onPreExecute is calling on MainThread. which means you can touch views.
doInBackground is calling on BackgroundThread. which means you can't touch views.
onPostExecute is calling on MainThread.
so while your job is going on inside doInBackground, you may want to notify user about job's progress but you can't notify user because it's calling on BackgroundThread. you need to jump to MainThread and AsyncTask provides you onProgressUpdate function to make it.
you can call publishProgress inside doInBackground.
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.
I used AsyncTask to request for a large chunk of data. When received, the data is processed inside the onPostExecute method. It may take a while to process the data.
Based from my understanding, AsyncTask is asynchronous and is independent from the UI.
Why does my Activity freezes onPostExecute?
Is it normal for an Activity to freeze if processing inside the onPostExecute method is too long?
How do I make it such that my Activity won't freeze onPostExecute?
You should do all your datasource operations like(database , network ,parsing the response.etc) in doInBackground method.
If you want update any ui updation in async task the use onProgressUpdate
I think you are performing any parsing operations in onPostExecute. try getting filtered or parsed data (lighter data) in onPostExecute.
Why does my Activity freezes onPostExecute?
According your post, you perform some time consuming operation on
PostExecute method. On PostExecute is running on UI thread, so it's
okay that you UI is freezed.
Is it normal for an Activity to freeze if processing inside the onPostExecute method is too long?
Yes, it's. You should perform long operation in doInBackground method
(non-UI thread)
How do I make it such that my Activity won't freeze onPostExecute?
Try to transfer your long time operation to doInBackground method and
in PostExecute just update UI according response, which you get after
operations in doInBackground method.
see Long Running Task You Need to Bind in doInBackground here you cannot Bind UI control Like Button, ImageView etc. After completion of doInBackground in onPostExecute you can Bind All Require Control, make sure here[onPostExecute] you not runnning Another task.
Make sure you are using doInBackground method in your AsynTask method.
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!
Why can an AsyncTask perform only one job? For example,
task = new SubAsyncTask(...); // assume the parameter is correct.
task.execute(...) //
task.execute(...)// calling once again, it throws exeception.
But a Handler can continously perform more than one task:
hd = new Handler(...); // assume the parameter is correct
hd.sendMessage(...); //
hd.sendMessage(...);// no exeception is thrown.
Is an AasyncTask object for a one-time job only? If I don't want to create multiple object for similar task, should I choose Handler?
Handler and AsyncTasks are way to implement multithreading with UI/Event Thread.
Handler allows to add messages to the thread which creates it and It also enables you to schedule some runnable to execute at some time in future.
Async task enables you to implement MultiThreading without get Hands dirty into threads. Async Task provides some methods which need to be defined to get your code works. in onPreExecute you can define code, which need to be executed before background processing starts. doInBackground have code which needs to be executed in background, in doInBackground we can send results to multiple times to event thread by publishProgress() method, to notify background processing has been completed we can return results simply. onProgressUpdate() method receives progress updates from doInBackground method, which is published via publishProgress method, and this method can use this progress update to update event thread, onPostExecute() method handles results returned by doInBackground method.
So, you dont need to call execute method on AsyncTask multiple TImes, instead you can invoke publishProgress.
Because that is how the class was designed. The idea is: do something with UI (show progress dialog, etc.), do work on background thread and return results, update UI. The Handler is fundamentally different: it lets you post messages, but it does not create a background thread for you. If you don't like how AsyncTask works, build something similar by using threads/executors and handlers.