Monday, June 10, 2013

Canceling an AsyncTask using the back button

After the last post about AsyncTask, there is a pending task to complete the example. A task running in background must be canceled if the user demand it. Thus, this is a good practice promoted by Google. Applications must be responsives. As well as canceling a task, we are going to learn how to capture the back button. AsyncTask will be canceled when back button is pressed by the user.

For capturing back button since Android 2.0 (Api level 5), Google has implemented a new method inActivity class which must be overridden. This method is onBackPressed(). In earlier versions, back button is captured with method onKeyDown() and is identified checking if key received as parameter is KeyEvent.KEYCODE_BACK.

So, in ProgressBarExampleActivity class from the last post we need two changes:
  • Add onBackPressed() method.
  • Set ProgressBarAsyncTask class as member of the class to be cancelled fromonBackPressed() method.

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
 
public class ProgressBarExampleActivity extends Activity {
  
   private static final String LOG_TAG = "PB_EXAMPLE";
   private EditText etNumSecondsM;
   private EditText etSecondsProgressedM;
  
   private Button bExitM;
   private Button bExecuteM;
   private ProgressBar pbDefaultM;
   private ProgressBarAsyncTask pbTaskM = null;
  
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      drawGUI();
   }
 
   /** Called when user press the back button */
   @Override
   public void onBackPressed()
   {
      Log.d(LOG_TAG, "Cancelling task");
 
      if( pbTaskM != null)
      {
         pbTaskM.cancel( false);
      }
   }
  
   public void drawGUI()
   {
      Log.d(LOG_TAG, "Creating Graphic Interface");
      setContentView(R.layout.main);
         
      //Text Editors
      etNumSecondsM = (EditText) findViewById(R.id.etNumSeconds);
      etSecondsProgressedM = (EditText) findViewById( R.id.etSecondProgressed);
         
      //Buttons
      bExecuteM = (Button) findViewById(R.id.bExecute);
      bExitM = (Button) findViewById(R.id.bExit);
         
      //Progress Bar
      pbDefaultM = (ProgressBar) findViewById( R.id.pbDefault);   
         
      // When the execution button is pressed, the AsyncTask is created and
      // executed.
      bExecuteM.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
               pbTaskM = new ProgressBarAsyncTask( pbDefaultM, etSecondsProgressedM);
               pbTaskM.execute( new Integer( etNumSecondsM.getText().toString()));
            }
      });
 
      bExitM.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {
             exit( RESULT_OK);
         }
      }); 
    }
     
    public void exit( int theResult)
    {
       setResult( theResult);
       finish();
    }
}


In the ProgressBarAsyncTask class we have to do next things:

  • Override onCancelled() method for resetting controls as we did in onPostExecute()method, because it will not be called after the cancellation.
  • In doInBackground() method call to isCancelled() method at the end of every iteration, to check if the task has been canceled and exit the loop.

No comments:

Post a Comment