Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

How to Add an AsyncTask to an Android Activity

5.00/5 (8 votes)
16 May 2014CPOL4 min read 42K  
Step-by-step instructions for adding an Async Task to an Android Activity

When Androids Dream

In Android, anything you do that takes longer than the proverbial two shakes of a lamb's tail* should be shunted off to an aync task, away from the UI thread.

* Electric sheep, electronic lambs, what's the diff?

This tip shows how to do that in step-by-step fashion; so, with aplomb but sans further ado, here they are:

0) First, add a class within the Activity that will use the async task like so:

Java
private class SomeNameTask extends AsyncTask<String, String, String> {

}

So what you have is a class within a class, such as:

Java
public class SongWriterActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_random_songwriter);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.random_songwriter, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private class GetRandomSongwriterTask extends AsyncTask<String, String, String> {

    }
}

As you can see, the class we just added ("GetRandomSongwriterTask" above) extends AsyncTask, and is embedded within the Activity class (which extends "ActionBarActivity").

As to naming your AsyncTask-extending method, appending "Task" is not necessary, but it reminds you/makes it obvious to any who may peruse your code, just what sort of class this is at a glance.

Flesh It Out

1) In Droidio (Android Studio - you are using Droidio, aren't you (all the cool kids (and geezers) do - Eclipse has been eclipsed)), right-click AsyncTask and select "Generate... > Implement Methods..."

You will see a dialog like this:

Image 1

Mash the "OK" button; this will add an empty doInBackground() method, which will automatically allow you to write async code (code that runs in the background/separate from the UI thread). Your class will now look like this:

Java
private class GetRandomSongwriterTask extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... strings) {
        return null;
    }

}

Prepare to Show the Result

2) If you want to do something with the return value of the background operation, add an onPostExecute() method, like so:

Java
@Override
protected void onPostExecute(String result) {

}

Your embedded AsyncTask class will now look like this:

Java
private class GetRandomSongwriterTask extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... strings) {
        return null;
    }

    @Override
    protected void onPostExecute(String result) {

    }
}

Send Me the Compiler That You Dream On

This example will show grabbing a random bit of data and displaying it. The onPostExecute() rather amazingly allows you access to the UI thread.

Before we get into the actual code for the two methods in that class, though, let's add some necessary "glue" code so that your class can be instantiated from the "outside world" (the UI).

3) Add a variable of the class at the top of your activity (prior to the onCreate() method, or any other method), like so:

Java
private GetRandomSongwriterTask _GetRandomSongwriterTask;

In context:

Java
public class SongWriterActivity extends ActionBarActivity {

    private GetRandomSongwriterTask _GetRandomSongwriterTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_random_songwriter);
    . . .

Note: If you need to step back and first create an Activity/Layout pair, see my previous tip on doing that here.

4) Now add a button to the related layout (xml) file. To do that, first select your .xml file (named something like activity_random_songwriter.xml, and located beneath \src\main\java\res\layout)

5) Now select the Design tab, which will show you your device. Drag a Button from the Widgets section of the palette, placing it where you want on the device. Once you have dragged it on to the device surface, select the Text tab below, and you can change the text of the button, either directly or (the preferred method) by adding a value to strings.xml (found within the values folder) and then referencing it like so in your .xml file:

XML
android:text="@string/get_random_songwriter"

This assumes you have an entry in strings.xml like this:

XML
<string name="get_random_songwriter">Get a random Songwriter</string>
Also, give the button a differentiating id, such as "getRandomSongwriterButton", like so:
XML
android:id="@+id/getRandomSongwriterButton"

It may look something like this on the design surface (if you had previously added an unrelated TextView widget with "Invoice #" as its text, that is):

Image 2

6) Now go back to your Activity file, and get a reference to that button and code up an onClick handler for it within the onCreate() method:

Java
Button getRandSwBtn = (Button) findViewById(R.id.getRandomSongwriterButton);
    getRandSwBtn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            //
        }
    });

In context:

Java
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_random_songwriter);

    Button getRandSwBtn = (Button) findViewById(R.id.getRandomSongwriterButton);
    getRandSwBtn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            //
        }
    });
}

Now we'll flesh out the code in the button's onClick event.

7) Instantiate the AsyncTask class like so:

Java
_GetRandomSongwriterTask = new GetRandomSongwriterTask();
_GetRandomSongwriterTask.execute();

In context:

Java
Button getRandSwBtn = (Button) findViewById(R.id.getRandomSongwriterButton);
getRandSwBtn.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        _GetRandomSongwriterTask = new GetRandomSongwriterTask();
        _GetRandomSongwriterTask.execute();
    }
});

We've kind of gotten ahead of ourselves here, though, because we're calling the GetRandomSongwriterTask's doInBackground() method (albeit indirectly, simply by instantiating the class and calling execute()) without that method actually doing anything.

We will remedy that now.

8) Add the following code to GetRandomSongwriterTask's doInBackground() method so that it looks like this:

Java
@Override
        protected String doInBackground(String... strings) {
            String songSlinger = "";

            List<String> songwriterNames = new ArrayList<String>();
            songwriterNames.add("J.S. Bach");
            songwriterNames.add("Jackson Browne");
            songwriterNames.add("Bob Dylan");
            songwriterNames.add("Woody Guthrie");
            songwriterNames.add("Merle Haggard");
            songwriterNames.add("Justin Hayward"); // Moody Blues
            songwriterNames.add("Chris Hillman");  // Byrds, Desert Rose Band, &c
            songwriterNames.add("Louis Jordan");
            songwriterNames.add("John Mellencamp");
            songwriterNames.add("Bruce Springsteen"); 
            songwriterNames.add("Merle Travis");
            songwriterNames.add("Dwight Yoakam"); 
            // Others include Carter, Cash, Crenshaw, Croce, Farner, Frey, Gallagher, Gates, Henley, Hiatt, Leadbelly, Lodge, Lennon/McCartney, Mozart, Sloan, Stevens, Townshend, ...  

            Random generator = new Random();
            int i = generator.nextInt(11);

            songSlinger = songwriterNames.get(i);
            return songSlinger;
        }

But how will we know which songwriter was (randomly) chosen? We could write it out using LogCat, but we want it to be part of the UI, so this is where the optional onPostExecute() method of the AsyncTask comes in handy.

9) First, though, drag a label to hold the returned value onto the design surface; give it a name such as SongWriterLabel:

XML
android:id="@+id/textViewSongwriter"

10) Now, add code like this to GetRandomSongwriterTask's onPostExecute() method:

Java
TextView txtVuSongwriter = (TextView) findViewById(R.id.textViewSongwriter);
txtVuSongwriter.setText(result);

And, voila! - here's what it looks like after the button is mashed (it would be "tapped" if this was a real device instead of an emulator) - the name of the masterful and charismatic leader of the Tympani 5 Image 3 is displayed:

Image 4

Of course, that was just "the luck of the draw" - it could have been any of those other cats just as easily (YMMV).

Dream a Little Dream of Your Own

The probability that you will want to generate a random songwriter name in your async task is exceedingly miniscule, approaching negative infinity. This was just shown as a simple example of how code can be added to an async task and its result can be displayed. Now replace it with something more useful (unless your users are very easily amused, and want to see the same names over and over again).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)