2012年9月7日金曜日

Android AsyncTaskでProgressDialogを表示 その2

Android AsyncTaskでProgressDialogを表示 その1
進捗を表示しながらバックグラウンドで処理を行うことってよくあるのですが、 まいどまいどAsyncTaskを作っていられないので自分なりの進捗を表示するAsyncTaskを作ってみました。
自分用のメモです。

ProgressAsyncTask
package com.example.helloandroid.tool;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;


/**
 * ProgressAsyncTask
 * プログレスダイアログを表示し、バックグラウンドで処理を行う抽象クラスです。
 * @param <Param>
 * @param <Result>
 *
 */
public abstract class ProgressAsyncTask<Param,Result> extends AsyncTask<Param,Bundle,Result>{
    private Context mContext;
    private ProgressDialog mProgressDialog;
    private Boolean isShowProgress;

    /**
     * コンストラクタ
     * @param context
     * @param procName
     */
    public ProgressAsyncTask(Context context){
        mContext = context;
    }

    /**
     * getIsShowProgress
     * プログレスダイアログが表示中かどうかを返します。
     * @return
     */
    public Boolean getIsShowProgress() {
        return isShowProgress;
    }

    /**
     * onPreExecute
     * 最初にUIスレッドで呼び出されます。
     * UIに関わる処理をします。
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showDialog();
        isShowProgress = true;
    }

    /**
     * onProgressUpdate
     * doInBackground内でpublishProgressメソッドが呼ばれると、 UIスレッド上でこのメソッドが呼ばれます。 
     * このメソッドの引数の型はAsyncTaskの二つ目のパラメータです。 
     * @param values
     */
    @Override
    protected void onProgressUpdate(Bundle... values) {
        super.onProgressUpdate(values);
        Bundle bundle = values[0];  
        if (bundle.containsKey("Message")){
            mProgressDialog.setMessage(bundle.getString("Message"));
        }
        if (bundle.containsKey("Max")){
            mProgressDialog.setMax(bundle.getInt("Max"));
        }
        if (bundle.containsKey("Progress")){
            mProgressDialog.setProgress(bundle.getInt("Progress"));
        }
    }

    /**
     * onPostExecute
     * doInBackground が終わるとそのメソッドの戻り値をパラメータとして渡して onPostExecute が呼ばれます。
     * このパラメータの型は AsyncTask を extends するときの三つめのパラメータです。
     * バックグラウンド処理が終了し、メインスレッドに反映させる処理をここに書きます。
     * @param result
     */
    @Override
    protected void onPostExecute(Result result) {
        super.onPostExecute(result);
        dismissDialog();
        isShowProgress = false;
    }

    /**
     * onCancelled
     * cancelメソッドが呼ばれるとonCancelledメソッドが呼ばれます。
     */
    @Override
    protected void onCancelled() {
        super.onCancelled();
        dismissDialog();
        isShowProgress = false;
    }

    /**
     * showDialog
     * プログレスダイアログを表示します。
     */
    public void showDialog() { 
        mProgressDialog = new ProgressDialog(mContext);
        mProgressDialog.setMessage(""); //途中でメッセージを変更するために必要
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setCancelable(true);
        mProgressDialog.setButton("キャンセル", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                cancel(true); // 非同期処理をキャンセルする
            } 
        });
        mProgressDialog.show();
    }

    /**
     * dismissDialog
     * ダイアログを終了します。
     */
    public void dismissDialog() {
        mProgressDialog.dismiss();
        mProgressDialog = null;
    }

    /**
     * setProgressMessage
     * プログレスダイアログのメッセージを設定します。
     * @param message
     */
    public void setProgressMessage(String message){
        Bundle data = new Bundle();
        data.putString("Message", message);
        publishProgress(data);
    }
    /**
     * setMax
     * プログレスダイアログの最大値を設定します。
     * @param max
     */
    public void setProgressMax(int max){
        Bundle data = new Bundle();
        data.putInt("Max", max);
        publishProgress(data);
    }
    /**
     * setProgress
     * プログレスダイアログの進捗値を設定します。
     * @param max
     */
    public void setProgress(int progress){
        Bundle data = new Bundle();
        data.putInt("Progress", progress);
        publishProgress(data);
    }


}


Activity
ボタンをクリックするとバックグラウンドでgetMethod1()とgetMethod2()を実行します。
import android.app.Activity;

import android.view.Menu;
import android.view.View;

import android.widget.Toast;

import com.example.helloandroid.R;
import com.example.helloandroid.service.ReceiveData;
import com.example.helloandroid.tool.DatabaseHelper;
import com.example.helloandroid.tool.ProgressAsyncTask;



public class MainActivity extends Activity {
    //Activityが破棄されても、オブジェクトを保持できるようにstaticで宣言する。   
    private static ProgressAsyncTask<?,?> mTask;  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //プログレスダイアログを再表示する。   
        if (mTask != null && mTask.getIsShowProgress()){   
            mTask.showDialog();   
        } 
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    } 

    @Override  
    protected void onPause() {   
        //プログレスダイアログを閉じる。   
        if (mTask != null && mTask.getIsShowProgress()) {   
            mTask.dismissDialog();    
        }   
        super.onPause();   
    }   


    /**
     * button1Click
     * @param view
     * button1クリック時の処理
     * 
     */
    public void button2Click(View view) {
        ProgressAsyncTask<Void,Boolean> task = new ProgressAsyncTask<Void,Boolean>(this){
            @Override
            protected Boolean doInBackground(Void... params) {
                ReceiveData receive = new ReceiveData(MainActivity.this);
                if (receive.getMethod1(this) == false ){
                    return false;
                }
                if (receive.getMethod2(this) == false) {
                    return false;
                }
                return true;
            }};
            mTask = task;
            task.execute();
    }

}

getMethod1()とgetMethod2()メソッドを定義しているクラスです。
package com.example.helloandroid.service;

import com.example.helloandroid.tool.ProgressAsyncTask;

import android.os.SystemClock;


public class ReceiveData {

    /**
     * getMethod1
     * @param task
     */
    public Boolean getMethod1(ProgressAsyncTask<?,?> task){
        task.setProgressMessage("Method1_Start");
        task.setProgressMax(10);
        for(int i=0; i<10; i++){
            task.setProgress(i+1);
            SystemClock.sleep(1000);
            if (task.isCancelled()) {      
                return false;                   
            } 
        }
        return true;
    }

    /**
     * getMethod2
     * @param task
     */
    public Boolean getMethod2(ProgressAsyncTask<?,?> task){
        task.setProgressMessage("Method2_Start");
        task.setProgressMax(20);
        for(int i=0; i<20; i++){  
            task.setProgress(i+1);
            SystemClock.sleep(1000);  
            if (task.isCancelled()) {      
                return false;                   
            } 

        }
        return true;
    }

}

0 件のコメント: