Wednesday 23 December 2015

How to execute Multiple Async Task at the same time

AsyncTask Overview

AsyncTask is an abstract Android class which helps the Android applications to handle the Main UI thread in an efficient way. AsyncTask class allows us to perform long lasting tasks/background operations and show the result on the UI thread without affecting the main thread.

An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.



 onPreExecute():
 This method is invoked before doInBackground method is called. This method is normally used to setup the progress bar in the UI.

doInBackground():
This method contains the code running for long time (For eg: Downloading files from internet or Uploading files to cloud server and so on). When execute method is called in UI main thread, this method is called with the parameters passed.

 onProgressUpdate():
This method is called by publishProgress at anytime from doInBackground. This method can be used to display any form of progress in the user interface.

onPostExecute():
This method is executed after doInBackground method completes processing. Result of the doInBackground is passed to this method.

The three generic types used by an asynchronous task are the following:
  1. Params, the type of the parameters sent to the task upon execution.
  2. Progress, the type of the progress units published during the background computation.
  3. Result, the type of the result of the background computation.
 Note : AsyncTask uses a thread pool pattern for running the stuff from doInBackground(). When first introduced the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. 
The pool size is 5, so at most 5 AsyncTasks can run simultaneously.
Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

 If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.

reference: AsyncTask | Android Developers
                                                                                                                                                  

This tutorial shows you how to execute multiple Async task at the same time parallel, and update the listview.

The first three ProgressBars updated by AsyncTask execute in normal approach by calling execute(), the last two ProgressBar updated by AsyncTask execute in parallel.


 MainActivity.java

 
public class MainActivity extends Activity {

    private static String url = "replace your request url here";

   
private static JSONArray contacts = null;
    private static ArrayList<HashMap<String, String>> contactList;
    private ListView mListView;
    private LazyAdapter adapter;
   
private ArrayList<HashMap<String, String>> datumList;

    public static final String TAG_DOCTORS = "doctor_details";
   
public static final String TAG_ID = "doc_id";
   
public static final String TAG_NAME = "name";
   
public static final String TAG_SPECIALIST= "specialist";
   
public static final String TAG_QUAL = "qualification";
   
public static final String TAG_EXP = "experience";
   
public static final String TAG_BRANCH = "branch";
   
public static final String TAG_THUMB_URL = "thumb_url";

   
public class MyAsyncTask extends AsyncTask<String, Integer, String> {

        ProgressBar myProgressBar;
        ImageView error, success;

       
public MyAsyncTask(ProgressBar target, ImageView error, ImageView success) {
            myProgressBar = target;
            error = error;
            success = success;          
        }

        @Override
        protected String doInBackground(String... urls) {
          
            String result = "success";
            ServiceHandler sh = new ServiceHandler();
            try{
            String jsonStr = sh.makeServiceCall(urls[0], ServiceHandler.GET);
            Log.d("Response: ", "> " + jsonStr);

            for (int i = 0; i < urls.length; i++) {
                   
datumList = parse(jsonStr);
                    publishProgress((int) (((i + 1) / (float) urls.length) * 100));  
            }
            } catch (Exception e) {
                e.printStackTrace();
                result = "fail";
            }
            return result;
        }

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

        @Override
        protected void onPostExecute(String result) {
            Log.e("Result size", result);
            if(!(result.equals("fail")))
            {
                this.success.setVisibility(View.VISIBLE);
            }              
            else if(result.equals("fail"))
            {
                this.myProgressBar.getProgressDrawable().setColorFilter(Color.RED,       Mode.SRC_IN);
                this.error.setVisibility(View.VISIBLE);
            }
           
adapter.notifyDataSetChanged();
        }
    }

    Button buttonStart;
    ProgressBar progressBar1, progressBar2, progressBar3, progressBar4, progressBar5;
    MyAsyncTask asyncTask1, asyncTask2, asyncTask3, asyncTask4, asyncTask5;
    ImageView error1, error2, error3, error4, error5, success1, success2, success3, success4,       success5;

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

       
contactList = new ArrayList<HashMap<String, String>>();
       
adapter = new LazyAdapter(MainActivity.this, contactList);

       
mListView = (ListView) findViewById(R.id.listView1);
       
mListView.setTextFilterEnabled(true);
       
mListView.setAdapter(adapter);

        intitView();
      
        buttonStart.setOnClickListener(new OnClickListener() {

            @Override
           
public void onClick(View v) {
                asyncTask1 = new MyAsyncTask(progressBar1,error1, success1);
                asyncTask1.execute("brokenUrl");
                asyncTask2 = new MyAsyncTask(progressBar2,error2, success2);
                asyncTask2.execute(url);
                asyncTask3 = new MyAsyncTask(progressBar3,error3, success3);
                asyncTask3.execute(url);
                asyncTask4 = new MyAsyncTask(progressBar4,error4, success4);
                StartAsyncTaskInParallel(asyncTask4,url);
                asyncTask5 = new MyAsyncTask(progressBar5,error5, success5);
                StartAsyncTaskInParallel(asyncTask5,"brokenUrl");
            }
        });
    }
 
    private void intitView() {
      
       
datumList = new ArrayList<HashMap<String, String>>();
      
        progressBar1 = (ProgressBar) findViewById(R.id.progressbar1);
        progressBar2 = (ProgressBar) findViewById(R.id.progressbar2);
        progressBar3 = (ProgressBar) findViewById(R.id.progressbar3);
        progressBar4 = (ProgressBar) findViewById(R.id.progressbar4);
        progressBar5 = (ProgressBar) findViewById(R.id.progressbar5);

        error1 = (ImageView) findViewById(R.id.error1);
        error2 = (ImageView) findViewById(R.id.error2);
        error3 = (ImageView) findViewById(R.id.error3);
        error4 = (ImageView) findViewById(R.id.error4);
        error5 = (ImageView) findViewById(R.id.error5);
      
        success1 = (ImageView) findViewById(R.id.success1);
        success2 = (ImageView) findViewById(R.id.success2);
        success3 = (ImageView) findViewById(R.id.success3);
        success4 = (ImageView) findViewById(R.id.success4);
        success5 = (ImageView) findViewById(R.id.success5);
      
        buttonStart = (Button) findViewById(R.id.start);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
   
private void StartAsyncTaskInParallel(MyAsyncTask task, String url) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
        else
            task.execute();
    }

   
public static ArrayList<HashMap<String, String>> parse(String jsonStr){

        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);

               
contacts = jsonObj.getJSONArray(TAG_DOCTORS);

                for (int i = 0; i <
contacts.length(); i++) {
                    JSONObject jsonObject =
contacts.getJSONObject(i);
                  
                    String id =
jsonObject.getString(TAG_ID);
                    String name =
jsonObject.getString(TAG_NAME);
                    String branch =
jsonObject.getString(TAG_BRANCH);
                    String
specialist = jsonObject.getString(TAG_SPECIALIST);
                    String quali =
jsonObject.getString(TAG_QUAL);
                    String expe =
jsonObject.getString(TAG_EXP);
                    String img_url =
jsonObject.getString(TAG_THUMB_URL);

                    HashMap<String, String> contact = new HashMap<String, String>();

                    contact.put(
TAG_ID, id);
                    contact.put(
TAG_NAME, name);
                    contact.put(TAG_BRANCH, branch);
                    contact.put(TAG_
SPECIALIST, specialist);
                    contact.put(TAG_QUAL, quali);

                    contact.put(TAG_EXP, expe);
                    contact.put(TAG_THUMB_URL,
img_url);

                   
contactList.add(contact);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return
contactList;
    }
}



 activity_main.xml


<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:orientation="vertical"
    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="com.example.androidparallelasynctask.MainActivity" >

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

    <
LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="5dp" >

        <ProgressBar
            android:id="@+id/progressbar1"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:indeterminate="false"
            android:max="100"
            android:progress="0" />

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/success1"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginLeft="2dp"
                android:layout_marginStart="2dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/success"
                android:visibility="invisible" >
            </ImageView>

            <ImageView
                android:id="@+id/error1"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/error"
                android:visibility="invisible" >
            </ImageView>
        </FrameLayout>
    </
LinearLayout>

    <
LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="5dp" >

        <ProgressBar
            android:id="@+id/progressbar2"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:max="100"
            android:progress="0" />

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/success2"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginLeft="2dp"
                android:layout_marginStart="2dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/success"
                android:visibility="invisible" >
            </ImageView>

            <ImageView
                android:id="@+id/error2"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/error"
                android:visibility="invisible" >
            </ImageView>
        </FrameLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="5dp" >

        <ProgressBar
            android:id="@+id/progressbar3"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:indeterminate="false"
            android:max="100"
            android:progress="0" />

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/success3"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginLeft="2dp"
                android:layout_marginStart="2dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/success"
                android:visibility="invisible" >
            </ImageView>

            <ImageView
                android:id="@+id/error3"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/error"
                android:visibility="invisible"/>
        </FrameLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="5dp" >

        <ProgressBar
            android:id="@+id/progressbar4"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:indeterminate="false"
            android:max="100"
            android:progress="0" />

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/success4"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginLeft="2dp"
                android:layout_marginStart="2dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/success"
                android:visibility="invisible" />

            <ImageView
                android:id="@+id/error4"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/error"
                android:visibility="invisible"/>
        </FrameLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="5dp" >

        <ProgressBar
            android:id="@+id/progressbar5"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:indeterminate="false"
            android:max="100"
            android:progress="0" />

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/success5"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginLeft="2dp"
                android:layout_marginStart="2dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/success"
                android:visibility="invisible" />

            <ImageView
                android:id="@+id/error5"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:contentDescription="@string/app_name"
                android:src="@drawable/error"
                android:visibility="invisible" />
        </FrameLayout>
    </LinearLayout>

    <ListView
        android:id="@+id/listView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>



Live Demo : 



Source code : Click here to download. 

Source link : Android-er

As always, Thanks a lot for reading...
Don't forget to share this post if you found it interesting!
If you find something to add to this post? or any other quick thoughts/hints that you think people will find useful? Share it in the comments & feedback's are most welcome. 

1 comment: