Wednesday, 26 September 2012

Asynchronous tasks in Android applications


Asynchronous tasks in Android applications




When we are writing an application and we want to perform a heavy background operation we have to start a new thread that will handle this operation and then publish the results on the UI thread for further processing. Having to manipulate threads can very often lead to complex pieces of code and it is pretty easy to mess things up really fast!

Android provides a class that enables proper and easy use of the UI thread and makes our life really easy. AsychTask is a class that allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called ParamsProgress and Result, and 4 steps (functions), calledonPreExecute, doInBackgroundonProgressUpdate and onPostExecute.

AsyncTask must be subclassed to be used and the subclass must override at least one method (doInBackground), and most often will override a second one ( onPostExecute). Now let's take a look at the three types used by an asynchronous task:
  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.
If a type is not used by an asynchronous task, then this type is marked as unused using the type Void. Now let's take a look at the 4 steps a task goes through when it is executed:
  1. onPreExecute: Invoked on the UI thread immediately after the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
  2. doInBackground: Invoked on a background thread after onPreExecute finishes executing. This function is used to perform background operations/computations that can take a long time. In this function we can use publishProgress to publish one or more units of progress. These values are published on the UI thread, in theonProgressUpdate step.
  3. onProgressUpdate: Invoked on the UI thread after a call to publishProgress.Usually it is used  to animate a progress bar.
  4.  onPostExecute: Invoked on the UI thread after doInBackground finishes executing. The result of the background computation is passed to this step as a parameter.
A task can be cancelled at any time by invoking cancel function. Below I am quoting an example of the use of AsynchTask:








package a.b;
 
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
 
public class Ayntaskdemo1Activity extends Activity {
    /** Called when the activity is first created. */
 private ProgressBar mProgressBar;
 private Button mCalculationButton;
  
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
        mCalculationButton = (Button) findViewById(R.id.calculation);
         
        mCalculationButton.setOnClickListener(new OnClickListener() {
    
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    CalculationTask task = new CalculationTask();
    task.execute();
   }
  });
    }
     
    /** Task that handles the procedure to store a route on the local database */
    private class CalculationTask extends AsyncTask<Void, Integer, Long> {
     
     @Override
     protected void onPreExecute() {
      // Initialize bar
      mProgressBar.setProgress(0);
     }
      
     @Override
     protected Long doInBackground(Void... data) {
      // Store route
      long counter = 0;
      for(int i = 1; i <= 10000000; i++) {
       counter += i;
       if(i % 100000 == 0) {
        publishProgress((int) i/100000);
       }
      }
       
      return counter;
     }
      
     @Override
     protected void onProgressUpdate(Integer... progress) {
      mProgressBar.setProgress(progress[0]);
        }
      
     @Override
     protected void onPostExecute(Long result) {
    Class gallery;
         try
         {
          gallery=Class.forName("a.b.gallery");
          Intent i=new Intent(Ayntaskdemo1Activity.this,gallery);
       //     startActivityForResult(i,PICK_EXISTING_PHOTO_RESULT_CODE);
                 startActivity(i);
         }
         catch(ClassNotFoundException e)
         {
          e.printStackTrace();
         }
      // Publish result
      Toast.makeText(getApplicationContext(), "Counter is " + result, Toast.LENGTH_LONG).show();
     }
    }
}

No comments:

Post a Comment