I am using AsyncTask for a long running task but I am getting the following error.
error in doInBackground====java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Why am I getting that error and what does it mean?
You can access GUI only from OnPostExecute and OnProgressUpdate.
You're probably running the task inside a non-UI thread.
The UI thread is set so that it loops. You can see where's the loop in a stack trace or in ddms while debugging:
...
MessageQueue.next() line: 146
Looper.loop() line: 110
...
This loop takes care of handling the messages, like the ones that an AsyncTask sends, with a Handler, like the one the AsyncTask is trying to set. If you're launching the task on a thread that has no looper set you get that message.
Usually this error comes when you change UI from asyntask which is not allowed, other way is to implement handler instead asyntask...
Because you don't post your code, so hard to find issue.
I think because you access UI Thread inDoInBackground. (for example: you access TextView, or Button, or EditText....) This is a most common error when use Asyntask.
you should post some parameter to publishProgress in DoInBackGround. then asyntask will send this param to onProgressUpdate and this method will act on UI Thread
Related
I am working on app that updates data for every 8 secs and the update was done using Async task. I am using loops to achieve this condition
while(const_val > update_val) {
new Asynctask().execute();
Thread.sleep(8000);
}
const_val will be constant and will be not be changed by any other methods.lets say this value will be 5.update_val will be updated and decremented when Asynctask is called and let's the value will be 10. So , the while loop executes until the condition is true and asynctask ,sleep are called .
When I use above while loop in a general method then UI gets locked and if I use the same loop in another asynctask there was an error saying "Only original thread that created a view hierarchy can touch its view "
You need to change your code to start the AsyncTask and have it provide an update via its onPostExecute() method. By calling Thread.sleep() you are sleeping the main thread (or UI thread) of your app, which is not good. You do not ever want to block the main thread. This article may help you better understand AsyncTask and threading in Android: http://po.st/Cei3m2
I don't think you should use a surrounding loop. Look at this example:
http://javatechig.com/android/progress-notification-in-android-example
the AsyncTask is a private inner class
the onPostExecute updates the UI with a message/cancels the load bar
This way you don't have to loop and the onCreate() can return instantly.
I have a thread which is started in onCreate() and this thread fetches some data.
Is it possible that before the thread is terminated should be able to update the ListView?
Now as the thread is not the UI thread, it cannot directly update the listview array adapter.
Is there a way out?
I was thinking that is it possible to trigger a Handler from thread whose runnable gets executed on main UI thread.
Not sure if I understood your problem completely, but I believe there are two ways to achieve what you want:
1- Start an AsyncTask instead of a thread. AsyncTask's onPostExecute() will run in the UI thread, which means you can do anything UI-related in there. You can start the AsyncTask in onCreate(), and, once it finished, it calls a method on your activity which does:
myAdapter.notifyDataSetChanged();
2- Use runOnUIThread()
Use your Activity's runOnUiThread(Runnable action)
link
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.
I am using AsyncTask to upload data to UI. i wrote the code to download data from server in a separate method and i am calling that method from doinBackground. It will give error because UI methods can't access from doInBackground.but, i want to access . any alternative process is there to access the UI method from doinBackground.?
any alternative process is there to access the UI method from doinBackground.?
Call publishProgress() in doInBackground(). Put your UI-updating logic in onProgressUpdate() of your AsyncTask. onProgressUpdate() will be called on the main application thread (a.k.a., UI thread) after you call publishProgress(). Here is a sample project demonstrating this.
Call runOnUiThread(Runnable action)
more here
Use doInBackground() just for tasks that :
Take some time
Are not UI related
Then you can implement AsyncTask.onPostExecute() to run code to handle those results on main UI thread from AsyncTask
From JavaDoc for AsyncTask.onPostExecute():
"Runs on the UI thread after doInBackground. ... "
As the others have pointed out, you can use runOnUiThread. But, it seems a little odd that you would want to do that in your doInBackground. If you are wanting to indicate progress to the user you would want to handle that in AsyncTask.onProgressUpdate and call publishProgress in your doInBackground.
You can read more about AsyncTask here: http://developer.android.com/reference/android/os/AsyncTask.html
-Dan
I am trying to call the invalidate() from asyntask thread. I am getting this error :
10-18 15:14:30.469: ERROR/AndroidRuntime(889): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
The line I have used is :
mainClass.myMapView.invalidate();//where mainClass=main UI class
Can anyone kindly suggest where my fault is ?
Thanks.
-
ahsan
You can't do anything UI-related from a different thread than the UI thread (thus its name). You should call invalidate() in either onPostExecute() or in onProgress(). Or, use runOnUiThread() (which is basically what publishProgress() / onProgress() does).