AsyncTask on Rescue!!!


“android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.”

erm… would you mind sorting this out too.

Well, that’s what I do here, don’t I?

Ok, so what I did wrong here?

You did the most common mistake every new Android developer do first time, so no need to panic. Even I did it several times, before I got to know about it. Mistakes make you learn new things. Those who didn’t make any mistakes, didn’t do anything at all. You should remember that.

Tell me when you start talking about Android again.

Oh, I caught in the flow ūüėȬ† So the main reason about why you got this exception is already mentioned there. Only those thread can access the View which created them. Mostly it’s the UI thread aka main thread. So you can’t create a new thread and call a method on any view in it.

I thought Android supports multi-threading???

Yeah, it does, but there’s a limitation to it. Android can’t allow multiple threads to access the Views, cause the timings of completion of threads are uncertain and due to this, the view, which actually makes the whole activity’s User Interface, would have looked odd, if allowed to be modified by more than one thread.

So there’s no way I can access the views from separate threads??

As far as I know, there’s no way. However I never ran into any situation which needs the view to be updated by separate threads and I don’t think you need it too. Before I get spammed by such kind of situations, let me clear my point. The most common situation where the view needs to be updated by separate thread is when you are loading certain data and on completion of it you want to update the view, such as dismissing a ProgressDialog or calling the setText() method on TextView.

Yeah, I am trying to do the same thing.

Gotcha then!!! Well, then your app can be saved by the almighty AsyncTask easily.

Now what is it? Don’t tell me to read the title this time, I’ve already read it.

Smart you!! Well AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. In other words, you can easily jump in and out to UI thread and any other thread using this class easily.

Would you mind telling me how to use it?

Yeah I was about to do it. But before that you should read what the official doc says about it. To use AsyncTask you have to subclass it. So the first step is to make a class and extend AsyncTask. Remember that AsyncTask supports generics, so if you want to supply parameters to it, use them. However in normal situation you won’t need it, thus I am making all parameters as void in my example.

Yeah, You are talking business now. Where’s the code example?

Suppose you are loading data from a web-service using a method loadData(). And till the method runs you want to show a ProgressDialog which should get dismiss on completion of loading. The code for the same would be:

class LoadingTask extends AsyncTask<Void,Void,Void>{
      protected Void onPreExecute() {
          ProgressDialog dialog=new ProgressDialog(getActivityContext());
          dialog.setMessage("Loading data ...");
          dialog.show();
      }
      protected Void doInBackground() {
          loadData();
      }
      protected Void onPostExecute() {
          dialog.dismiss();
     }
 } 

And if you want to update the UI thread in between the loading, you need to call publishProgress() method, which takes an argument usually an Integer, about how much loading has been done. The call to publishProgress() will ultimately call onProgressUpdate() method which runs on UI thread. So jumping in and out of UI thread is easier with this. On completion of you loading, the onPostExecute() gets called.

The thing to remember here is all methods except doInBackground(), gets called on UI thread, where the Views are accessible, thus the loading taks should be in doInBackground() and updating view should be in either onProgressUpdate() (when you want to update View in between the loading) or in onPostExecute() (whne you want to update View after the loading is finished). onPreExecute() gets called before the loading starts, and runs on UI thread too.

Ok I got it, but how do I start the task?

You need to make an object of the class we just made and call execute() method on it. Remember that the execute() method can take parameters to be passed in the task, but generally I declare all the variables needed as class variable, so never needed it. The type of parameters passed is decided by the generics we declare in the AsyncTask. You can notice that all the method takes variable arguments.

LoadingTask task=new LoadingTask();
task.execute(); 

Ok, Finally I got it, thanks for saving my app again.

If this post helped you then just share this post as much as you can, so that we can save more lives. You can also click on any of the share button available and share this post with your friends, collegues or anyone who can get benefit with it. You can post your questions and comments below and, can also vote up this post.

I want to hear more from you.

You can check my¬†stackoverflow¬†profile and look for answers I posted there (probably vote on them too ūüėČ ). You can also ask your questions there and provide me a link to answer them. If you want a complete blog post on them, leave me a comment, and I’ll get back to you soon.

Thanks for listening,

Abhi,

The Creator

profile for Creator at Stack Overflow, Q&A for professional and enthusiast programmers