I would like to know how it works. I have read the documentation a couple of times but don’t get the idea.
I noticed that in some cases onPostExecute does nothing.
Can anyone please give me a little explanation?
AsyncTask is a class derived from Thread and provides you a simple and proper way of doing some things in the background with the ability of notifying the UI Thread.
In order to use it you should create a class, which extends it and define the type parameters. They are Params, Progress and Result. Read about them more here.
onPostExecute() is a method which is called when doInBackground() finished it's execution, but onPostExecute() is run on the UI Thread. So, you can notify the UI about the work has been done.
You can see an example of AsyncTask usage here.
The <Void, Void, Long> part is what in Java is called Generics. It is used in those classes where the original coder wants it to be used no matter what the types the "end user" will choose.
Typically you use onPre/PostExecute() when you want to start/stop a progress dialog.
If you want to update the UI during the progress without a progress dialog you can do things in onProgressUpdate() (i.e.: you're loading images from web and displaying them as they get loaded)
If you have a dialog with progress bar you'll have to use all of them to update the progress bar.
This post explains AsyncTask concept nicely with diagram !
{onPostExecute()} is used when you want to do something after completing your background task {(doInBackground())}.
For example,
start Progress Bar # {onPreExecute()}
running Progress Bar # {doInBackground()}
stop Progress Bar # {onPostExecute()}
Related
I'm developing an Android app that has a basic structure: activity that requests some action from AsyncTask implementer. The implementer has 3 custom methods that should be able to update UI thread with a Dialog and a postExecute() that should update UI thread with a failuer Dialog if an exception is thrown. Here are some questions:
Where should I create the Dialog object? In the activity class or the AsyncTask implementer? What general guidelines should I follow?
Can I update UI thread with a Dialog without waiting for postExecute()?
How can I update UI thread with a picture? Should I create a custom Dialog or is there an easier way?
If the updates - as dialogs with pictures - come one after another, in a sequence how should I deal with it? Should I create some kind of queue? How would you do it?
Thank you in advance :)
1)There's a couple of different ways you can do this. But personally I usually create the dialog in onPreExecute of the AsyncTask, so that the UI for the task is completely self contained.
2)Yes. You can do it in onProgressUpdate. doInBackground should call publishProgress() which will cause onProgressUpdate to be called on the UI thread.
3)Too few details- where do you want the picture? In an existing image view? On top of the current layout? If you just want to display it in a dialog box, an AlertDialog with custom layout would probably work.
4)Depends on the app. Do you want the user to see all the images, or is it ok to miss images in the middle if a new one is sent?
I have an AsyncTask that calls a native method, and I want to report the progress.
Is it possible? I can't change the Native since its a black box to me, but I can read its output which is a file, which I can parse as progress.
Thanks,
Eli
As much as I know, its not possible using async task, but its doable using combination of threads and handler.
you can use this pattern:
Use a Class with 2 threads, one for the worker and one for the progress report.
The last updates the progress bar (which is a member).
When finished, call the handler message method to dismiss the progress bar.
You can grab the code from here.
Eli
i am making lot of HTTP calls in my applications & switches between the views, now i'm handling the Http calls in a thread, but i want to make user to wait when the http request in progress. How to do this?. I just need to show a wait cursor or loading string.
You can use a ProgressDialog whit a Handler.
Android Progress Dialog Example
Android's indeterminate ProgressDialog tutorial
Cheers
I find the name a bit misleading, but you should show a ProgressBar while background operations conclude.
May be this will helpful. You have to make a background operation using thread concept like AsyncTask. Using this you can hide the actual work from the UI part. And AsyncTask will get unallocated after your operations are completed.
Create a subclass of AsyncTask
Use AsyncTask to do background work
Call onPreExecute() to initialize task
Use a progressbar with setIndeterminate(true) to enable the indeterminate mode
Call onProgressUpdate() to animate your progressbar to let the user know some work is being done
Use incrementProgressBy() for increment progressbar content by a specific value
Call doInBackground()and do the background work here
Catch an InterruptedException object to find end of background operation
Call onPostExecute() to denote the end of operation and show the result
please tell me best way to write this.
I need one generic AsyncTask for webservice call with all possible errror handling. Also a callback for updating UI/ showing error message.
I have found few approches :
by adding Generic parameter to async task
making asynctask as abstract
for handling error giving handler object.
This is actually very easy to do with an AsyncTask.
AsyncTask has 4 functions. 3 of them run on the UI Thread so you can update the UI as much as you like. 1 of the functions runs in the background so you can do things that take as long as is necessary, such as calling your webservice.
You do not need a formal callback function. AsyncTask.onPostExecute() handles this for you.
There is a great example in the Android documentation that shows how to download a file exactly as you are trying to do with the webservices connection. You will extend AsyncTask and create your own DownloadFilesTask just like in the example.
The whole thing is started with a single line of code:
new DownloadFilesTask().execute(...)
The four functions are:
onPreExecute() - Useful for displaying a ProgressBar or other
UI elements.
doInBackground() - Take as long as you want, but don't update
the UI from here. Instead, call publishProgress() as often as you
like. That will internally call onProgressUpdate() where you can
incrementally update the UI, or your ProgressBar, if you want.
onProgressUpdate() - Optional show progress updates or increment
a ProgressBar. This function only gets called in response to calling
publishProgress() from doInBackground().
onPostExecute() - Done, dismiss() your ProgressBar, update
the UI, process any errors saved in doInBackground(), and jump to
the next section of your code.
Error Handling:
All errors are trapped in doInBackground(). You should save an int errorCode and/or String errorMessage in your DownloadFilesTask class, and return; from doInBackground() when an error occurs. Then, process and report the error in onPostExecute().
See this question for several answers. They all involve storing any exception thrown by doInBackground in a field and checking it in onPostExecute. I like this answer posted by #dongshengcn, which encapsulates this into a subclass of AsyncTask, then you can override onResult and/or onException as necessary.
Error
05-12 11:56:45.793: ERROR/AndroidRuntime(505): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
what i have done
i have a list view inside my activity and i need to populate the listview by doing the following:
mylistview.setAdapter(new CustomAdapter());
now there is already too much pressure on my UI thread so , thought of calling this method inside a AsynTask.
Another problem
there is a progress dialog that shows in my acitivity when the user clicks the button to populate the listview. when i put everything inside one thread the progress dialog does not show. i had asked a question on stackoverflow about why the progress dialog does not show and i had got a reply saying that i need to put all the extra tasks inside another thread.
i have also read the updating UI in android given on android developer website:
but over there all we do is make a new runnable and post the runnable to the Handler of the UI thread so that when the UI is free, the runnable will be executed.
But how does the above solve my purpose? i mean the UI thread is still executing the instructions.
The only way i can take the load of the UI thread is if i make another thread and put all the work over there... but android does not allow this?
what is wrong with my understanding(if there is anything wrong)? How do i solve this problem
thank you in advance.
Android does allow you to put the extra work in a different thread AND publish the results on the UI thread, using AsyncTask. Add the UI update stage in the onPostExecute() method of the AsyncTask and you should be good-to-go. onPostExecute() is performed on the UI thread, the example in the AsyncTask Documentation is a great one.
Also, if you build your application properly, and don't use graphics a lot, there should not be too much work for the UI thread during the application run. Move everything that doesn't absolutely bound to the UI on a separate thread. AsyncTask is a very convenient way to do it.
AsyncTask is the correct way to solve your problem. Where you are running into difficulty is exactly what to put into the AsyncTask. Call mylistview.setAdapter(); from the onProgressUpdate or onPostExecute methods. So do something like this:
void setProgress(Integer progress){ myprogressbar.setValue(progress); }
void setAdapter(CustomAdapter result){ mylistview.setAdapter(result); }
private class LongRunningTask extends AsyncTask<String, Integer, CustomAdapter> {
protected Long doInBackground(String... urls) {
CustomAdapter res = null;
// do all the work to BUILD the custom adapter, calling publishProgress() as progress gets made
publishProgress(<progress value>);
return res;
}
protected void onProgressUpdate(Integer... progress) {
setProgress(progress);
}
protected void onPostExecute(CustomAdapter result) {
setAdapter(result);
}
}
That should fix the threading issue and let you set the progress bar.