Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Working with AsyncTask in Android

The AsyncTask class was created to facilitate the processing in the background and update the data in graphical interface. See in this article how this process works

Programming in Android is not an impossible task, we simply have too have knowledge in Java, because Google provides a complete and well documented API access. In these devices, tasks can be simultaneously performed in two ways: by "parallelism" itself and the Pseudo-parallelism. The parallelism depends on the amount of processor cores has, namely, if the processor has two cores, so only two tasks can be performed simultaneously. Now, if the processor has only one core, then it executes only one task at a time, but this is not feasible because it would not be possible to listen to music, open the browser and write a text at the same time.

For this problem to be solved was born Pseudo-parallelism, which is nothing more than an internal system that lets you perform the tasks a little at a time at a given time, ie the processesschedulerputs the task running for a certain time and, ending this time, we have the "time-slice", which takes the process that is running and puts it at the end of the queue of processes that are ready to run. This process can also go to the locked state, meaning that waits for some external event. This time-slice happens in a totally imperceptible time, which gives the feeling of parallelism, even when there is only one processing core.

Within the Android platform you can run tasks in parallel, for this are used the threads that allow the creation of execution of lines that run in "parallel". When there are very heavy processing within the Android it is extremely advisable to make use of threads, as if that processing happens within the main Activity can cause a bad impression to the user, because the screen is locked while processing takes place, and the user can find that the application broke.

The use of threads is quite simple in Android, but to update the graphical interface with the information processed there is a job a little higher, and the use of Handlers. The AsyncTask class was created to facilitate that kind of background processing and updating the data in the graphical interface.

Here, we also have a complete course regarding Android development, if you want to get more into these subject, feel free:

AsyncTask

The AsyncTask encapsulates the whole process of creating and Handler Threads and to use it is simple, as a class must be created and extended to AsyncTask class. Because it is a generic class, it is defined as follows:

AsyncTask<Parameter,Progress,Result>

  • The parameters are the type of data that will be passed as parameter to the methods of AsyncTask, and any value can be passed.
  • Progress is the kind of data that show the progress on the screen as the percentage of download. Always must be passed an Integer to use percentage.
  • The result is the return that will be working to be displayed in the user interface. Understand return as the return of processing thread to the main thread.

There are four methods that can be overridden in AsyncTask:

  • The onPreExecute method is always executed before the thread is started, and is where are placed the messages that appear on the screen to the user. This method is not required and it runs on the same thread that the graphical interface;
  • The doInBackground method is responsible for all the heavy processing because it runs in a separate thread. While the information is processed the user's screen is not locked. Its return is passed as parameter to the method onPostExecute. And this is the only method that has a mandatory implementation.
  • The onPostExecute method is receiving the return of doInBackground: it is called using a Handler and its execution occurs on the same thread that the graphical interface, that is, we can update the graphical interface within it;
  • The onProgressUpdate method is responsible for receiving the information to show the percentage of the download on the screen to the user. Also it runs on the same thread that the graphical interface.

Listing 1 shows the structure of a class that extends AsyncTask.

Listing 1. AsyncTask Structure

public class YouClass extends AsyncTask<String,Integer,Integer>{
	  @Override
	  protected void onPreExecute(){
				  //Code
	  }
	  @Override
	  protected Integer doInBackground(String... params) {
				  //Code
	  }
	  @Override
	  protected void onPostExecute(Integer number){
				  //Code
	  }
	  protected void onProgressUpdate(Integer… params){
				  //Code
	  }
}

It will now be shown a practical example where the application will receive a URL that contains only an image, which will be downloaded and displayed on your screen. All processing is done in a separate thread.

The layout will have three elements: one EditText to receive the URL, a Button to trigger the action of downloading the image, and an ImageView responsible for showing the bitmap on the screen. Listing 2 shows this code.

Listing 2. XML code layout.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/editText"
        android:text="Download" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/button" />

</RelativeLayout>

Figure 1 shows how this layout should look.

Figure 1. Layout in the emulator

The manifest file must contain the following information, shown in Listing 3. The permission to access the internet should be given, once the image will be downloaded from the internet.

Listing 3. Android Manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="asynctaskexample.mrbool.com.asynctaskmrbool">

    <uses-permission android:name="android.permission.INTERNET" />
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

The code responsible for downloading the image has no big secrets and can be seen in Listing 4. This code is contained within an class Auxiliar.

Listing 4. Code to download the image.

package asynctaskexample.mrbool.com.asynctaskmrbool;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * Created by Fabricio on 10/19/2015.
 */
public class Auxiliar {
    public static Bitmap downloadImage(String url) throws IOException {
        URL address;
        InputStream inputStream;
        Bitmap image;
        address = new URL(url);
        inputStream = address.openStream();
        image = BitmapFactory.decodeStream(inputStream);
        inputStream.close();
        return image;
    }
}

Because it contains a static method, this class does not need to be instantiated to access the downloadImage method. Here is defined a URL containing the image and its address is passed by parameter. An object of type InputStream is responsible for receiving the image information, which for now is still coded. Finally, the Bitmap object type receives the return of the static method decodeStream contained within the BitmapFactory class, which is responsible for converting bitmap to what was stored encrypted within the inputStream.

The inputStream has closed its connection and the picture is returned.

We'll look at how to build the core code of the application. Let's start with the Listing 5 code.

Listing 5. Part of the code.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    image = (ImageView) findViewById(R.id.imageView);
    btnDownload = (Button) findViewById(R.id.button);
    edtAddress = (EditText) findViewById(R.id.editText);
    Log.i("AsyncTask", "Screen elements created and Thread attributes: " + Thread.currentThread().getName());
    btnDownload.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.i("AsyncTask", "Thread Clicked Button: " + Thread.currentThread().getName());
            callAsyncTask(edtAddress.getText().toString());
        }
    });
}

private void callAsyncTask(String address) {
    TaskDownload download = new TaskDownload();
    Log.i("AsyncTask", "AsyncTask being called by Thread: " + Thread.currentThread().getName());
    download.execute(address);
}

The basics of any Android application can be seen in this code where objects of type ImageView, Button and EditText have their representatives attached to the XML. The button is combined with a onClickListener, which will identify when it is pressed and implement the content of the onClick method. In this case, we have the call to callAsyncTask method, passing as parameter the content entered into the EditText. When calling this method, you instantiate an object of type TaskDownload.

It is very important to understand that you should never call the AsyncTask methods separately, as they will not work: for proper operation we should use the object of the extended class of AsyncTask and call the method to run through the vestments that are needed, ensuring so proper operation.

Note also that every piece of code has a Log.i to be able to observe the Android log where each task is being performed.

In Listing 6 we can observe the class that extends the AsyncTask.

Listing 6. Class responsible for running parallelism

private class TaskDownload extends AsyncTask<String, Void, Bitmap> {
    @Override
    protected void onPreExecute() {
        Log.i("AsyncTask", "Showing ProgressDialog on the screen Thread: " + Thread.currentThread().getName());
        load = ProgressDialog.show(MainActivity.this, "Please wait ...", "Downloading image ...");
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        Bitmap bitmapImage = null;
        try {
            Log.i("AsyncTask", "Downloading image on Thread: " + Thread.currentThread().getName());
            bitmapImage = Auxiliar.downloadImage(params[0]);
        } catch (IOException e) {
            Log.i("AsyncTask", e.getMessage());
        }
        return bitmapImage;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap != null) {
            image.setImageBitmap(bitmap);
            Log.i("AsyncTask", "Showing Bitmap Thread: " + Thread.currentThread().getName());
        } else {
            Log.i("AsyncTask", "Error at btnDownload the image " + Thread.currentThread().getName());
        }
        Log.i("AsyncTask", "Removing ProgressDialog from screen in Thread: " + Thread.currentThread().getName());
        load.dismiss();
    }

}

The class that extends the AsyncTask class is private within your main Activity. Within the TaskDownload class we note all of the methods discussed above:

  • The onPreExecute is enabling a ProgressDialog, responsible for giving feedback to the user, showing that the image is being downloaded;
  • The doInBackground method is calling the static method auxiliar responsible for downloading the image and store it in a Bitmap object type. As a parameter is passed to position 0 (first position) of the String array that is in the method signature;
  • The onPostExecute method checks if the bitmap received by parameter (return on doInBackground method) is null: if not, it makes the picture appears in the ImageView previously implemented. At the end of the method, ProgressDialog is removed from the screen.

Note that in all Logs we have a call to Thread.currentThread.getName(), that is used to display the log in which thread each part of the code is running. In Listing 7 you can see the result shown in Log.

Listing 7. Logs of threads

10-19 21:41:19.324  12195-12195/asynctaskexample.mrbool.com.asynctaskmrbool I/AsyncTask? Screen elements created and Thread attributes: main
10-19 21:45:09.200  12195-12195/asynctaskexample.mrbool.com.asynctaskmrbool I/AsyncTask? Thread Clicked Button: main
10-19 21:45:09.200  12195-12195/asynctaskexample.mrbool.com.asynctaskmrbool I/AsyncTask? AsyncTask being called by Thread: main
10-19 21:45:09.207  12195-12195/asynctaskexample.mrbool.com.asynctaskmrbool I/AsyncTask? Showing ProgressDialog on the screen Thread: main
10-19 21:45:09.227  12195-12210/asynctaskexample.mrbool.com.asynctaskmrbool I/AsyncTask? Downloading image on Thread: AsyncTask #1
10-19 21:45:09.602  12195-12195/asynctaskexample.mrbool.com.asynctaskmrbool I/AsyncTask? Showing Bitmap Thread: main
10-19 21:45:09.602  12195-12195/asynctaskexample.mrbool.com.asynctaskmrbool I/AsyncTask? Removing ProgressDialog from screen in Thread: main

Note that most of the logs shows the command that was executed in the main Thread, except for Downloading Image, which runs within the Thread AsyncTask#1, ie, it is actually running off the main thread in a run-line different.

The following Figures 2, 3 and 4 show the end result of this operation.

Figure 2. Home screen

Figure 3. Waiting for the download to complete

Figure 4. Final result

Figure 2 shows the screen before being inserted into the URL to capture the image, while Figure 3 shows the screen while the user is waiting for the completion of the download image. Finally, Figure 4 shows the final result to the user.

Conclusion

As can be seen, the AsyncTask class is not impossible to be worked with: with the concepts presented here it becomes very useful, for example, to access Web-Services and receive or send data.

You can also find the complete source code of the example implemented here in the top of the page, through Source link.

I hope you all enjoyed and until the next opportunity!



Fabrí­cio Galdino is a software expert and has worked with IT analysis and business development for more than five years. It has extensive experience with testing, back and front-end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login