Androidプログラマへの道 〜 Moonlight 明日香 〜 - 非同期処理をキャンセルする
バックグラウンド処理を途中でキャンセルしたい場合, AsyncTaskクラス内でProgressDialogクラスを利用する.

キャンセル処理

  • MainActivity.java
    • AsyncTask#onPreExecuteメソッド
      • ProgressDialog#setCancelableメソッドで, キャンセルを有効にする.
      • ProgressDialog#setOnCancelListenerメソッドで, ハンドラを設定する.
    • AsyncTask#doInBackgroundメソッド
      • AsyncTask#isCancelledメソッドでキャンセルをチェックする. キャンセルの場合, バックグラウンド処理を中止する.
    • AsyncTask#onCancelledメソッド
      • ProgressDialog#dismissメソッドで, プログレスバーのダイアログを閉じる.
    • DialogInterface.OnCancelListener#onCancelメソッド
      • AsyncTask#cancelメソッドで, バックグラウンド処理にキャンセルを通知する.
  注) プログレスバーが表示されているときに戻るキーを押すと, キャンセルイベントが発生する.
package com.moonlight_aska.android.asynctask02;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener; import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {
  Context mContext = this;
  ProgressDialog mDialog = null;
  SampleAsyncTask mTask = null;
  Button mBtn = null;

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

    mBtn = (Button)findViewById(R.id.btn_id);
    mBtn.setOnClickListener(this);
  }

  @Override
  public void onClick(View v) {
    // TODO Auto-generated method stub
    mTask = new SampleAsyncTask();
    mTask.execute("param");
  }

  // AsyncTaskのサブクラス
  private class SampleAsyncTask extends AsyncTask<String, Integer, Long> implements OnCancelListener {
    // バックグラウンド処理の前に実行される処理
    @Override
    protected void onPreExecute() {
      // TODO Auto-generated method stub
      Log.v("AsyncTask", "onPreExecute");
      // Progress Dialogの表示
      mDialog = new ProgressDialog(mContext);
      mDialog.setTitle("しばらくお待ちください");
      mDialog.setMessage("非同期処理テスト中....");
      mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      mDialog.setMax(100);
      mDialog.setProgress(0);
      mDialog.setCancelable(true);   // Cancel有効に
      mDialog.setOnCancelListener(this);
      mDialog.show();
    }

    // バックグラウンド処理
    @Override
    protected Long doInBackground(String... params) {
      // TODO Auto-generated method stub
      Log.v("AsyncTask", "doInBackground");
      try {
        for (int i=0; i<10; i++) {
          Thread.sleep(1000);
          if (isCancelled()) {  // キャンセルチェック
            Log.v("AsyncTask", "CANCEL");
            break;
          }
          publishProgress((i+1)*10);
        }
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      return 100L;
    }

    // バックグラウンド処理完了後に実行される処理
    @Override
    protected void onPostExecute(Long result) {
      // TODO Auto-generated method stub
      Log.v("AsyncTask", "onPostExecute");
      mDialog.dismiss();
    }

    // 更新処理
    @Override
    protected void onProgressUpdate(Integer... values) {
      // TODO Auto-generated method stub
      mDialog.setProgress(values[0]);
    }

    // バックグラウンド処理中止後に実行される処理
    @Override
    protected void onCancelled() {
      // TODO Auto-generated method stub
      Log.v("AsyncTask", "onCancelled");
      mDialog.dismiss();
    }

    // Progress Dialogで, キャンセルが入力
    @Override
    public void onCancel(DialogInterface dialog) {
      // TODO Auto-generated method stub
      Log.v("Dialog", "CANCEL");
      cancel(true);
    }
  }
}
  • 動作例