Pages

Wednesday, December 19, 2012

Using AsyncTask

A very usefull class in Android is the AsyncTask.

It's an easy way to make your application do something in background and bringing the results of this action to the UI. In this post, I'm going to show you how you can use AsyncTask in your application.
I made a simple App that generates a random number between 0 and 10 every second. After 7 times, it returns the sum of these generated values. In the meanwhile, each time a number is generated, the user will be informed about it.

First of all

Before we start the AsyncTask to do its job, we have to give it some parameters to work with.
While working, we want to see the progress of the AsyncTask.
And of course, eventually, we want to have a result.

If we want to create an AsyncTask, we need to specify these 3 things. Our AsyncTask class will extend AsyncTask<Params, Progress, Result>

In this case, we will make a RandomCountingTask.
The parameters we want to give to the task are the number of times it should generate a number and how large this generated number may be. These are both Integers, in this case 10 the maximum value of a number and 7 for the amount of numbers we want.

The Progress in this case is the generated number, so this is also an Integer.

The Result will also be an Integer, the sum of all generated numbers.

So our task has to look like this:

class RandomCountingTask extends AsyncTask<Integer, Integer, Integer>{ }

If we would write this in Eclipse, we would have to add unimplemented methods. This is the method doInBackground(Integer... params){}


AsyncTask 'Lifecycle'

Since the AsyncTask is created to do stuff in background and bring results and progress to the UI, it has methods on the Main Thread (UI) and methods on a single Worker Thread (Background).
This is how it goes:



Code

Now without further ado, here's the code of this simple example:


package com.bonappetit.demos.asynctask;

import java.util.Random;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class AsyncTaskDemo extends Activity implements OnClickListener {

 private TextView txtMain;
 private Button btnStartStop;
 private AsyncTask<Integer, Integer, Integer> countingTask;
 private boolean isCounting;



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

 }

 private void setUpViews() {
  txtMain = (TextView)findViewById(R.id.txtAsyncTaskDemoMainText);
  btnStartStop = (Button)findViewById(R.id.btnAsyncTaskDemoStartStop);
  btnStartStop.setOnClickListener(this);
  btnStartStop.setText("Start"); 

 }



 @Override
 public void onClick(View v) {
  if(v == btnStartStop){
   if(!isCounting){
    txtMain.setText("");//clear the text
    countingTask = new RandomCountingTask(); // create a new task
    //a task can be executed only once;
    Integer[] values = new Integer[2];
    values[0] = 10; //number between 0 and 10
    values[1] = 7; //generate 7 times
    countingTask.execute(values);
   }else{
    countingTask.cancel(true);
   }
  }  

 }

 public boolean isCounting() {
  return isCounting;
 }

 public void setCounting(boolean isCounting) {
  this.isCounting = isCounting;
 }


 class RandomCountingTask extends AsyncTask<Integer, Integer, Integer>{


  @Override
  protected void onPreExecute() {
   super.onPreExecute();
   Toast.makeText(AsyncTaskDemo.this, "Started counting", Toast.LENGTH_SHORT).show();
   setCounting(true);
   btnStartStop.setText("Stop");
  }

  @Override
  protected Integer doInBackground(Integer... params) {
   int maxValue = params[0];
   int maxTimes = params[1];
   int sum = 0;
   int randomNumber;
   Random r = new Random();
   for(int i = 0; i<maxTimes; i++){
    randomNumber = r.nextInt(maxValue);
    sum += randomNumber;
    publishProgress(randomNumber);   

    try {
     Thread.sleep(1000); //Sleep for 1 second
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   return sum;
  }  

  @Override
  protected void onProgressUpdate(Integer... values) {
   super.onProgressUpdate(values);
   txtMain.append("Added " + values[0] + " to the sum\n");
  }



  @Override
  protected void onPostExecute(Integer result) {
   super.onPostExecute(result);
   setCounting(false);
   Toast.makeText(AsyncTaskDemo.this, "Stopped counting", Toast.LENGTH_SHORT).show();
   txtMain.append("Result is " + result);
  }  

  @Override
  protected void onCancelled() {
   super.onCancelled();
   setCounting(false);
   Toast.makeText(AsyncTaskDemo.this, "Counting was cancelled", Toast.LENGTH_SHORT).show();  
  }
 }

}


Important notes

  • There is a limit of AsyncTasks to use in your application (another post on this will follow)
  • An instance of an AsyncTask can only be executed once.
  • Something like Integer... can be one or more integers

3 comments:

  1. Sorry, but I believe you are leaking somehow the main activity.
    Your asynctask is an inner class and as far as I know inner classes keep a reference to their outer classes.
    In this case, the main activity cannot be garbage collected when it is destroyed so if you i.e rotate the screen when your task is performing you probably gonna notice the leak. To avoid that I think you should make the asynctask class static.
    Now an interesting question, how would you do when you need a reference to the activity/context in an async task?

    ReplyDelete
  2. Really, it's a great blog.
    Thank you for sharing useful information with us.
    Morpheus tv apK is the best application which streams our movies and tv shows with high-quality videos just of no cost it’s free.
    I think it may useful for each one. If you want to know more, then check

    Morpheus TV App For Android Phone

    Morpheus TV App For Android Phone

    ReplyDelete
  3. Fantasy Power 11 if you have a good knowledge of Cricket you Can play daily online ,live cricket games,
    cricket online games,best cricket games,play cricket online, cricket game online at best cricket games app for android phones to win real
    cash and amount to instant approve in your bank or Paytm wallet.play cricket online

    ReplyDelete