Thursday, March 24, 2016

AsyncTask vs Thread + Handler


This post show how to implement using AsyncTask and Thread/Handler to perform the same function: doing something in background and update UI elements (ProgressBar and TextView).

This video show how it run on Android Emulator running Android N, in Multi-Window.


AsyncTask

MainActivity.java
package com.blogspot.android_er.androidasynctask;

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

public class MainActivity extends AppCompatActivity {

    Button btnStart;
    ProgressBar progressBar;
    TextView textMsg;

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

        progressBar = (ProgressBar)findViewById(R.id.progress);
        textMsg = (TextView)findViewById(R.id.msg);

        btnStart = (Button)findViewById(R.id.start);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyAsyncTask myAsyncTask = new MyAsyncTask(progressBar, textMsg);
                myAsyncTask.execute();
            }
        });
    }

    class MyAsyncTask extends AsyncTask<Void, Integer, Void>{

        ProgressBar pBar;
        TextView tMsg;

        public MyAsyncTask(ProgressBar pBar, TextView tMsg) {
            super();
            this.pBar = pBar;
            this.tMsg = tMsg;
        }

        @Override
        protected Void doInBackground(Void... params) {
            for(int i=0; i<=10; i++){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                publishProgress(i);
            }
            return null;
        }

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

        @Override
        protected void onPostExecute(Void aVoid) {
            tMsg.setText("finished");
        }
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidasynctask.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start"/>

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:indeterminate="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="10"
        android:progress="0"/>
    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>



Thread + Handler

MainActivity.java
package com.blogspot.android_er.androidthreadhandler;

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

import org.w3c.dom.Text;

public class MainActivity extends AppCompatActivity {

    Button btnStart;
    ProgressBar progressBar;
    TextView textMsg;

    private Handler handler = new Handler();

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

        progressBar = (ProgressBar)findViewById(R.id.progress);
        textMsg = (TextView)findViewById(R.id.msg);

        btnStart = (Button)findViewById(R.id.start);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyThread myThread = new MyThread(progressBar, textMsg);
                myThread.start();
            }
        });
    }

    class MyThread extends Thread{

        ProgressBar pBar;
        TextView tMsg;

        public MyThread(ProgressBar pBar, TextView tMsg) {
            super();
            this.pBar = pBar;
            this.tMsg = tMsg;
        }

        @Override
        public void run() {

            for (int i = 0; i <= 10; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //is accessed from within inner class, needs to be declared final
                final int finalI = i;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        pBar.setProgress(finalI);
                    }
                });
            }

            handler.post(new Runnable() {
                @Override
                public void run() {
                    tMsg.setText("finished");
                }
            });
        }
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidthreadhandler.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start"/>

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:indeterminate="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="10"
        android:progress="0"/>
    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>



next:
- HandlerThread example

related:
Load something from Internet using URLConnection and BufferedReader, in AsyncTask
Load something from Internet using URLConnection and BufferedReader, in Thread


No comments: