Android AsyncTask Example

android.os.Handler and android.os.AsyncTask class are all support asynchronous task in android. To use Handler, you need to create a new child thread object for each task. When task is finished, it will send a message to main thread Handler to update UI components. But when multiple tasks are executed simultaneously, it is not easy to control threads accurately.

So android.os.AsyncTask is introduced in android sdk since version 1.5. It make android asynchronous task implementation more easier. You do not need to create Handler instance and you also do not need to create and attach asynchronous task thread instance to the handler object.

android asynctask process flow

1. AsyncTask Definition.

Below is AsyncTask class definition java code. It is an abstract class which you must extends to create a sub class to use. There are three generic types in the class definition also, they have below meanings.

public abstract class AsyncTask<Params, Progress, Result> { 
          ...
}

  1. Params : The input parameter type for asynctask’s execute(Params…params) and doInBackground(Params…params) method input parameter array.
  2. Progress : The input parameter type for publishProgress(Progress… values) and onProgressUpdate(Progress… values) method input parameter array. When you use publishProgress(Progress… values) method to publish current task progress data, onProgressUpdate(Progress… values) method will be invoked.
  3. Result : Represent the return data type of doInBackground(Params… params) method. It is also the input parameter type of both onPostExecute(Result result) and onCancelled(Result result) method.

2. AsyncTask Methods.

Create a sub class which extends android.os.AsyncTask. Then you can override it’s methods to implement different purpose.

  1. execute(Params… params) : This method is invoked in java code to start the asynchronous task.
  2. void onPreExecute() :  Used to do some UI operation before performing background tasks.
  3. String doInBackground(Integer… inputParams) : Run immediately after onPreExecute() is completed, it is used to perform more time-consuming operations. This method accepts the input parameters and returns the calculated results. During the execution, you can call publishProgress(Progress… Values) to update the progress information.
  4. void onProgressUpdate(Progress… values) : This method will be invoked when execute publishProgress(Progress… Values) method in java code. Generally, we update UI component’s status such as text, progress percentage in this method.
  5. void onPostExecute(String result) :  When background task complete, this method will be invoked automatically. Parameter result’s value is just which doInBackground(Params… params) method returned.
  6. void onCancelled(String result) : This method will be invoked when AsyncTask’s cancel(boolean cancel) method is invoked.
READ :   Use OkHttp3 To Upload And Download Json File Example

3. AsyncTask Notes.

  1. Must create AsyncTask instance in UI thread.
  2. Must invoke execute(Params… params) method in UI thread.
  3. onPreExecute(),doInBackground(Params… params),onProgressUpdate(Progress… values),onPostExecute(Result result) are all callback methods, do not call them by code manually.
  4. Can not update UI component’s data in doInBackground(Params… params) method.
  5. Each AsyncTask instance can run only once, if run one AsyncTask instance twice, there will throw an exception.

4. AsyncTask Example.

android async task example

android async task log output

activity_async_task.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:layout_editor_absoluteY="8dp"
    tools:layout_editor_absoluteX="8dp">

    <Button
        android:id="@+id/executeAsyncTaskButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Execute Async Task" />

    <Button
        android:id="@+id/cancelAsyncTaskButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Cancel Async Task" />

    <ProgressBar
        android:id="@+id/asyncTaskProgressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/asyncTaskLogTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="" />

    </ScrollView>
</LinearLayout>

AsyncTaskActivity.java

package com.dev2qa.example;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class AsyncTaskActivity extends AppCompatActivity {

    private final String ASYNC_TASK_TAG = "ASYNC_TASK";

    private Button executeAsyncTaskButton;
    private Button cancelAsyncTaskButton;
    private ProgressBar asyncTaskProgressBar;
    private TextView asyncTaskLogTextView;

    private MyAsyncTask myAsyncTask;

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

        setTitle("dev2qa.com - AsyncTask Example");

        this.executeAsyncTaskButton = (Button)findViewById(R.id.executeAsyncTaskButton);
        this.executeAsyncTaskButton.setEnabled(true);

        this.cancelAsyncTaskButton = (Button)findViewById(R.id.cancelAsyncTaskButton);
        this.cancelAsyncTaskButton.setEnabled(false);

        this.asyncTaskProgressBar = (ProgressBar)findViewById(R.id.asyncTaskProgressBar);
        this.asyncTaskLogTextView = (TextView)findViewById(R.id.asyncTaskLogTextView);

        executeAsyncTaskButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Need to create a new MyAsyncTask instance for each call,
                // otherwise there will through an exception.
                myAsyncTask = new MyAsyncTask();
                myAsyncTask.execute(Integer.parseInt("10"));

                executeAsyncTaskButton.setEnabled(false);
                cancelAsyncTaskButton.setEnabled(true);
            }
        });

        cancelAsyncTaskButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Cancel a running task, then MyAsyncTask's onCancelled(String result) method will be invoked.
                myAsyncTask.cancel(true);
            }
        });
    }

    // MyAsyncTask is used to demonstrate async task process.
    private class MyAsyncTask extends AsyncTask<Integer, Integer, String>{

        // onPreExecute() is used to do some UI operation before performing background tasks.
        @Override
        protected void onPreExecute() {
            asyncTaskLogTextView.setText("Loading");
            Log.i(ASYNC_TASK_TAG, "onPreExecute() is executed.");
        }

        // doInBackground(String... strings) is used to execute background task, can not modify UI component in this method.
        // It return a String object which can be used in onPostExecute() method.
        @Override
        protected String doInBackground(Integer... inputParams) {

            StringBuffer retBuf = new StringBuffer();
            boolean loadComplete = false;

            try
            {
                Log.i(ASYNC_TASK_TAG, "doInBackground(" + inputParams[0] + ") is invoked.");

                int paramsLength = inputParams.length;
                if(paramsLength > 0) {
                    Integer totalNumber = inputParams[0];
                    int totalNumberInt = totalNumber.intValue();

                    for(int i=0;i < totalNumberInt; i++)
                    {
                        // First calculate progress value.
                        int progressValue = (i * 100 ) / totalNumberInt;

                        //Call publishProgress method to invoke onProgressUpdate() method.
                        publishProgress(progressValue);

                        // Sleep 0.2 seconds to demo progress clearly.
                        Thread.sleep(200);
                    }

                    loadComplete = true;
                }
            }catch(Exception ex)
            {
                Log.i(ASYNC_TASK_TAG, ex.getMessage());
            }finally {
                if(loadComplete) {
                    // Load complete display message.
                    retBuf.append("Load complete.");
                }else
                {
                    // Load cancel display message.
                    retBuf.append("Load canceled.");
                }
                return retBuf.toString();
            }
        }

        // onPostExecute() is used to update UI component and show the result after async task execute.
        @Override
        protected void onPostExecute(String result) {
            Log.i(ASYNC_TASK_TAG, "onPostExecute(" + result + ") is invoked.");
            // Show the result in log TextView object.
            asyncTaskLogTextView.setText(result);

            asyncTaskProgressBar.setProgress(100);

            executeAsyncTaskButton.setEnabled(true);
            cancelAsyncTaskButton.setEnabled(false);
        }

        // onProgressUpdate is used to update async task progress info.
        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.i(ASYNC_TASK_TAG, "onProgressUpdate(" + values + ") is called");
            asyncTaskProgressBar.setProgress(values[0]);
            asyncTaskLogTextView.setText("loading..." + values[0] + "%");
        }

        // onCancelled() is called when the async task is cancelled.
        @Override
        protected void onCancelled(String result) {
            Log.i(ASYNC_TASK_TAG, "onCancelled(" + result + ") is invoked.");
            // Show the result in log TextView object.
            asyncTaskLogTextView.setText(result);
            asyncTaskProgressBar.setProgress(0);

            executeAsyncTaskButton.setEnabled(true);
            cancelAsyncTaskButton.setEnabled(false);
        }
    }
}
(Visited 1,431 times, 4 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.