Home > Researches > Understanding AsyncTask – Once and Forever

Understanding AsyncTask – Once and Forever

This article describes the usage of AsyncTask class in Android.

Motivation

Android modifies the user interface via one thread, the so called UI Thread. If you perform a long running operation directly on the UI Thread, for example downloading a file from the internet, the user interface of your application will “freeze” until the corresponding task is finished. When this happens it is very easy for the user to perceive your application as slow.

As a concrete example of a bad implementation and what happens when a long running operation is done on the UI Thread, I want to refer to one of my previous tutorials: Creating A Simple RSS Application in Android. Well, that application is working fine, and it does what it is supposed to do – parse an XML feed and display the headlines in a ListView. The “vulnerability” of that application is that the network access is done directly on the UI Thread which makes the application to “freeze” while the XML feed is downloaded (take a look at point number 5 to see).
When I created that tutorial I wanted to make it as simple as possible without dealing with more advanced topics like asynchronous tasks. The intent of tutorial was to show the working process with feeds on a high level. But I promise you, by the end of this article you will be able to fix it and have a Cool Rss App that runs smoothly! :)

To provide a good user experience all long running operations in an Android application should run asynchronously. To achieve this we will be using the AsyncTask class.

What does AsyncTask do?

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 order to use the AsyncTask class, you must extend it and override at least the doInBackground() method.

The most common methods you will need to implement are these:

   1. onPreExecute() – called on the UI thread before the thread starts running. This method is usually used to setup the task, for example by displaying a progress bar.

   2. doInBackground(Params…) – this is the method that runs on the background thread. In this method you should put all the code you want the application to perform in background. Referring to our Simple RSS Aplication, you would put here the code that downloads the XML feed and does the parsing. The doInBackground() is called immediately after onPreExecute(). When it finishes, it sends the result to the onPostExecute().

   3. onProgressUpdate() – called when you invoke publishProgress() in the doInBackground().

   4. onPostExecute(Result) – called on the UI thread after the background thread finishes. It takes as parameter the result received from doInBackground().

AsyncTask is a generic class, it uses 3 types: AsyncTask<Params, Progress, Result>.

  1. Params – the input. what you pass to the AsyncTask
  2. Progress – if you have any updates, passed to onProgressUpdate()
  3. Result – the output. what returns doInBackground()

Once a task is created, it can be executed like this:
new DownloadTast().execute(url1, url2, urln);

Code Example

This is a simple skeleton of an AsyncTask implementation.


public class AsyncTaskTestActivity extends Activity {

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      //Starting the task. Pass an url as the parameter.
      new PostTask().execute("http://feeds.pcworld.com/pcworld/latestnews");
   }

   // The definition of our task class
   private class PostTask extends AsyncTask<String, Integer, String> {
   @Override
   protected void onPreExecute() {
      super.onPreExecute();
      displayProgressBar("Downloading...");
   }

   @Override
   protected String doInBackground(String... params) {
      String url=params[0];

      // Dummy code
      for (int i = 0; i <= 100; i += 5) {
        try {
          Thread.sleep(50);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
         publishProgress(i);
      }
      return "All Done!";
   }

   @Override
   protected void onProgressUpdate(Integer... values) {
      super.onProgressUpdate(values);
      updateProgressBar(values[0]);
   }

   @Override
   protected void onPostExecute(String result) {
      super.onPostExecute(result);
      dismissProgressBar();
   }
   }
}

AsyncTasks are great for performing tasks in a separate thread, they have however one weakness. While the AsyncTask is in the middle of the work and the screen of device is rotated, you’ll notice that the application crashes. This happens because when rotating the device screen a configuration change occurs, which will trigger the Activity to restart. The AsyncTask reference to the Activity is invalid, an onPostExecute() will have no effect on the new Activity. How to handle this sort of issues is described in: Dealing with AsyncTask and Screen Orientation, which I highly recommend reading it if you are concerned to deliver stable Android applications.

About these ads
  1. March 30, 2012 at 7:10 pm

    very nice tutorial and well written…thanks

  2. April 6, 2012 at 1:45 pm

    Where is displayProgressBar defined?

    • April 6, 2012 at 5:44 pm

      It’s a mock method.
      The idea is that in the onPreExecute() you could display a progress bar, and in the onPostExecute() hide it.

      But that should not be difficult to define a such method:
      displayProgressBar(){
      ProgressBar bar=(ProgressBar)findViewById(R.id.progressBar);
      bar.setVisibility(View.VISIBLE); //View.INVISIBLE, or View.GONE to hide it.
      }

      (Not sure if the code will compile, as I wrote it directly in comments.)

  3. joseph
    April 22, 2012 at 9:50 am

    i dont understand it at all,, how can i link it with a simple rss application?

  4. Catherine
    May 21, 2012 at 12:37 pm

    Hi, I’m totally new on Android and thanks a lot for your previous tutorial about creating a simple rss feed reader. Do you mind to show how this AsyncTask class should work with the rss feed application you’ve created previously? Many thanks.

    • June 25, 2012 at 9:09 pm

      See my reply below, @Rahul.

  5. June 6, 2012 at 5:44 am

    > new PostTask().execute(“http://feeds.pcworld.com/pcworld/latestnews”)

    How would I do something like this?

    new PostTask().execute(aStringArray, anInteger, aBoolean)

    • June 25, 2012 at 9:06 pm

      Just change the parameter types when your class extends AsyncTask:

      private class PostTask extends AsyncTask<String[], Integer, Boolean>{
      //
      }
      
      • David E
        March 1, 2013 at 5:46 am

        This doesn’t work for me –

        I need to pass a HttpHost and String to my task, which is to return a String. So I have:

        private class processQueryTask extends AsyncTask{

        but the compiler is expecting the processQueryTask.execute() to have arguments:
        processQueryTask.execute(HttpHost…)

        I.e., it won’t take the String as an argument.

        Any advice would be greatly appreciated!

  6. Rahul
    June 25, 2012 at 8:38 pm

    How do you sync with the RSS application?

    • June 25, 2012 at 9:03 pm

      From the onCreate() method, extract the code within try{} catch() block, and put it inside the doInBackground() method of the PostTask class. Then you can start your task in onCreate() like this: new PostTask().execute().

      Of course you should make sure the parameters of execute() method matches the AsyncTask class arguments, and “heandlines” and “links” arrays can be accessed globally.

      • November 10, 2012 at 7:56 pm

        Hi. Great tutorials but I am struggling with implementing the code from rss tutorial with this one. Can you please copy the code that suppose to be within doInbackground method?

  7. Jacek Milewski
    June 27, 2012 at 5:27 am

    Just to convince you to use AsyncTasks:
    It is a must when performing any network operations to run it outside of UI Thread.

    Android 4.0 even throws an exception if your app tries to use network in main thread:
    NetworkOnMainThreadException

    On older android versions exception will not be thrown, however user experience can harm

  8. July 17, 2012 at 11:19 pm

    Hi!

    Great tutorial! But there’s a thing I still don’t undestand. In the method doInBackground(String… params) you return a String, but you never use it.

    My question is why you need to return something in this method? And if I need to use the string returned, how do I get it?

    Thanks!

    • July 18, 2012 at 6:01 pm

      Most of the cases you would want to return something from the doInBackground(), though of course there may be cases where you don’t to return nothing.
      But suppose you are parsing an XML rss feed, or downloading an image from the internet (all of this stuff done in doInBackground()). In this case you would want to display the XML content, or the image downloaded in your activity, right?

      The doInBackground() will return any data type you want. The data returned is passed to onPostExecute(Object result), where you have the ability to receive that data and display it in your Activity.

      Therefore, the return type of doInBackground() should match the paramter of onPostExecute().
      You may return any object type you want from the doInBackground() and do whatever you want with it in onPostExecute(), or nothing.

      • July 19, 2012 at 2:21 am

        Great, thanks! Now I understand it completly!

        Great toturial by the way!

  9. nelzkie
    August 4, 2012 at 9:24 am

    Hey where is the Download Link

  10. akash
    September 20, 2012 at 12:56 pm

    can u give its full source code bcoz i can’t use it. i am new on android then plzzzz

  11. Ajeet
    October 16, 2012 at 5:05 am

    You’ve used private class PostTask which is illegal modifier, it can only be public, final and abstract permissible.

    • October 27, 2012 at 9:26 pm

      It’s not illegal, you can do that.
      Here the PostTask class is declared as a inner class, with private access modifier so other classes could not instantiate it.

  12. sotos lolos
    October 22, 2012 at 8:06 pm

    Could someone write an implementation of the RSSReader app with use of AsyncTask?? Would be very helpful

  13. Abdallah Musmar
    November 5, 2012 at 4:08 pm

    Thanks a lot. Thank you so much!!

  14. Qadir Suh
    November 15, 2012 at 1:10 pm

    Mashallah… nice tutorial for bigginers. :)

  15. linbo
    November 20, 2012 at 7:55 am

    I have doubt, what’s the purpose of this method? publishProgress(i);
    As In doInBackground, won’t access UI usually.

    • linbo
      November 20, 2012 at 8:05 am

      Sorry, check the document, this is an API which can publish progress unit.

  16. IIDreII
    November 23, 2012 at 6:43 am

    I love you, man. This is was clearest tutorial I read about Asynctask after banging my head on my desk for the past three days. I seriously went from being completely confused to understanding this perfectly. Thank you. Seriously, THANK YOU. Saved me a lot of headache.

  17. December 17, 2012 at 2:29 pm

    Why do you need a URL? for new PostTask.Execute(URL); What should I put in there if I’m posting a facebook post or logging in facebook using their sdk.

  18. Mayaa
    February 11, 2013 at 6:36 pm

    Great post… Thanku so much.. Even thishttp://androidtechstuffs.blogspot.in/2013/01/why-and-how-to-use-asynctask.html is also helpful. have a look..

  19. February 24, 2013 at 8:20 am

    I got error, saying that I have to define methods: displayProgressBar(), updateProgressBar() and dismissProgressBar(). Are they not predefined??

    • March 31, 2013 at 8:13 pm

      They are dummy methods to show what the AsyncTask callbacks may be used for. So yes, they are not defined as this is out of scope of this article.

  20. Ravindar
    March 8, 2013 at 5:01 am

    Good…but i need full clarity

  21. Guest
    March 22, 2013 at 9:51 pm

    Hi, I tried to implement this method on your RSS application but it keeps throwing an error i don’t understand. what am i doing wrong. I am trying to display a simple text while the rss feeds are fetched. below is my doInBackground code i came up with

    PS: i made some changes to the code from your previous post


    protected String doInBackground(String... params) {
    try { //Retrieval
    URL url = new URL("http://feeds.pcworld.com/pcworld/latestnews");

    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    factory.setNamespaceAware(false);
    XmlPullParser xpp = factory.newPullParser();
    xpp.setInput(getInputStream(url), "UTF_8");
    boolean insideItem = false;
    // Returns the type of current event: START_TAG, END_TAG, etc..
    int eventType = xpp.getEventType();
    while (eventType != XmlPullParser.END_DOCUMENT) {
    if (eventType == XmlPullParser.START_TAG) {

    if (xpp.getName().equalsIgnoreCase("item")) {
    insideItem = true;
    } else if (xpp.getName().equalsIgnoreCase("title")) {
    if (insideItem)
    listItems.add(new ListItem(Html.fromHtml(xpp.nextText()).toString())); //extract the headline
    } else if (xpp.getName().equalsIgnoreCase("link")) {
    if (insideItem)
    linkItems.add(xpp.nextText()); //extract the link of article
    }
    }else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
    insideItem=false;
    }

    eventType = xpp.next(); //move to next element
    }

    } catch (MalformedURLException e) {
    e.printStackTrace();
    } catch (XmlPullParserException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    } // end of retrieval

    return "";
    }

  22. Guest
    March 23, 2013 at 6:20 pm

    The code actually works fine… i forgot to include ” ” in the manifest of the new project… x_x

    • March 23, 2013 at 6:31 pm

      Glad that you solved the issue yourself! :)

  23. Rameez Hassan Chaudhry
    March 30, 2013 at 8:47 pm

    AweSome Man! very helpful thanks :)

  24. April 4, 2013 at 11:19 pm

    how ican chang the code of simple-rss-application to become corectly

    please help

  25. Hitesh Patel
    April 12, 2013 at 1:01 pm

    How can I use AsyncTask to download thousands of data, like I have 1500 records, I would like to display it, in listview but My listview will update after every 100 records download, data will name, address, image, phono_number etc….

  26. May 31, 2013 at 6:07 pm

    Thank you very much, very clear tutorial, I understand the whole concept now and it helped me a lot in my project :D

  27. Edward
    August 19, 2013 at 6:48 am

    Thanks! This is by far the most comprehensive explanation of AsynTask I’ve found on the internet. Thanks again for a great tutorial!

  28. January 20, 2014 at 2:03 am

    Very good.

  29. March 1, 2014 at 5:20 am

    You should take part in a contest for one of the most useful sites on the
    web. I most certainly will highly recommend this website!

  30. lajili
    March 23, 2014 at 12:54 am

    very simple and clear
    thanks

  31. April 24, 2014 at 11:33 am
  1. March 17, 2012 at 1:20 pm
  2. March 30, 2012 at 7:48 pm
  3. May 23, 2012 at 4:30 pm
  4. January 4, 2013 at 2:00 pm
  5. January 9, 2013 at 10:30 pm
  6. January 11, 2013 at 4:30 am
  7. January 11, 2013 at 9:32 am
  8. February 9, 2013 at 9:30 pm
  9. February 26, 2013 at 4:30 am
  10. March 4, 2013 at 8:08 am
  11. March 18, 2013 at 9:00 am
  12. March 26, 2013 at 1:00 pm
  13. September 2, 2013 at 1:51 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 507 other followers

%d bloggers like this: