Sunday, February 5, 2017

android - AsyncTask progress update example

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f3f4ee"
    >
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Do AsyncTask"
        android:layout_margin="25dp"
        android:layout_gravity="top|center_horizontal"
        />
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/btn"
        android:layout_gravity="bottom|center_horizontal"
        app:layout_anchorGravity="bottom|center_horizontal"
        android:textSize="20sp"
        android:gravity="center_horizontal"
        />
</android.support.design.widget.CoordinatorLayout>
MainActivity.java

package com.cfsuman.me.androidcodesnippets;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {
    private Context mContext;
    private Activity mActivity;

    private CoordinatorLayout mCLayout;
    private Button mButton;
    private TextView mTextView;


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

        // Get the application context
        mContext = getApplicationContext();
        mActivity = MainActivity.this;

        // Get the widget reference from XML layout
        mCLayout = (CoordinatorLayout) findViewById(R.id.coordinator_layout);
        mButton = (Button) findViewById(R.id.btn);
        mTextView = (TextView) findViewById(R.id.tv);

        // Initialize a new click listener for button widget
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Empty the TextView
                mTextView.setText("");
                // Execute the async task
                new DownloadTask().execute("Task 1","Task 2","Task 3","Task 4");
            }
        });
    }

    /*
        AsyncTask
            AsyncTask enables proper and easy use of the UI thread. This class allows you to perform
            background operations and publish results on the UI thread without having
            to manipulate threads and/or handlers.
    */
    private class DownloadTask extends AsyncTask<String,Integer,List<String>>{
        // Before the tasks execution
        protected void onPreExecute(){
            mTextView.setText(mTextView.getText() + "\nStarting task....");
        }

        // Do the task in background/non UI thread
        protected List<String> doInBackground(String...tasks){
            // Get the number of task
            int count = tasks.length;
            // Initialize a new list
            List<String> taskList= new ArrayList<>(count);

            // Loop through the task
            for(int i =0;i<count;i++){
                // Do the current task task here
                String currentTask = tasks[i];
                taskList.add(currentTask);

                // Sleep the UI thread for 1 second
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                /*
                    publishProgress
                        void publishProgress (Progress... values)
                            This method can be invoked from doInBackground(Params...) to publish
                            updates on the UI thread while the background computation is still
                            running. Each call to this method will trigger the execution of
                            onProgressUpdate(Progress...) on the UI thread.
                            onProgressUpdate(Progress...) will not be called if
                            the task has been canceled.

                        Parameters
                            values Progress: The progress values to update the UI with.
                */
                // Publish the async task progress
                // Added 1, because index start from 0
                publishProgress((int) (((i+1) / (float) count) * 100));

                // If the AsyncTask cancelled
                if(isCancelled()){
                    break;
                }
            }
            // Return the task list for post execute
            return taskList;
        }


        /*
            onProgressUpdate
                void onProgressUpdate (Progress... values)
                    Runs on the UI thread after publishProgress(Progress...) is invoked.
                    The specified values are the values passed to publishProgress(Progress...).

                Parameters
                    values Progress: The values indicating progress.
        */
        // After each task done
        protected void onProgressUpdate(Integer... progress){
            mTextView.setText(mTextView.getText() + "\nCompleted...." + progress[0] + "%");
        }

        // When all async task done
        protected void onPostExecute(List<String> result){
            mTextView.setText(mTextView.getText() + "\n\nDone....");
            for (int i=0;i<result.size();i++){
                mTextView.setText(mTextView.getText() + "\n" + result.get(i));
            }
        }
    }
}