新人成長記録13th

AsyncTaskについて

今回もAndroidにおける非同期処理について書いていきます
前回はThreadでの非同期処理を書きました
今回はAsyncTaskについてです

AsyncTask

Threadでは、基本的にUIスレッドを使うことはできませんでした(Handlerを使えばUIスレッドへ投げられますけどね)
AsyncTaskではUIスレッドと関係のある非同期処理を行うことができます
例えば、長い処理の間の待ちとしてプログレスダイアログを表示することができます
現在の処理が全体の何パーセントか、何件中の何件処理完了とかですね
このようなダイアログを表示することでユーザにも現在の進行が分かるようになります

progress_spinner  progress_percent

プログラムの内容は以下のようになります。

public class AsyncFrag extends AsyncTask<Integer, Integer, Boolean> {

	Context context;
	ProgressDialog dialog;


	public AsyncFrag(Context context){
		this.context = context;
	}

	@Override
	protected void onPreExecute() {
		dialog = new ProgressDialog(context);
		dialog.setTitle("Please wait");
		dialog.setMessage("Loading data...");
		dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		dialog.setCancelable(false);
		dialog.setMax(100);
		dialog.show();
	}

	@Override
	protected Boolean doInBackground(Integer... params){

		for(int i=0;i<100;i++){
			if(isCancelled()){
				return false;
			}
			try {
				Thread.sleep(300/(i%3 + 1));
				publishProgress(1);
			}catch (Exception e){}
		}
		publishProgress(1);
		return true;
	}

	protected void onProgressUpdate(Integer... params){
		dialog.incrementProgressBy(1);
	}

	@Override
	protected void onPostExecute(Boolean result) {
		if(dialog != null && dialog.isShowing()) {
			dialog.dismiss();
		}
	}

	@Override
	protected void onCancelled(){
		Log.d("debug","onCancelled");
		if(dialog != null && dialog.isShowing()) {
			dialog.dismiss();
		}
	}
}

AsyncTaskを使うときには必要な引数は3つあります
1つ目は、doInBackgroundメソッドの引数となっており、メインの処理で呼ぶ際に受け渡す値となります
2つ目は、opProgressUpdateメソッドの引数となっており、表示しているダイアログの更新などに使えます
3つ目は、doInBackgroundメソッドの返り値で、onPostExecuteメソッドの引数となっています

2つ目の引数に関しては、onProgressUpdateメソッドの必要がない場合には、Voidを指定してもいいですし、なにか適当に指定するのもいいです

それでは、このクラスの中での処理の流れを説明していきます
最初に、onPreExecuteが処理されます
ここでは、UIを変更することができるので、ここでダイアログを表示します

次にdoInBackgroundが処理されます
ここは、Uiスレッドとは異なるスレッドでの処理なのでUIの編集はできませんので注意が必要です
publishProgressでonProgressUpdateに処理を渡すことができますので、処理の中でのループで呼ぶようにしてあげると、ダイアログの更新を頻繁にでき、処理完了までの割合などが伝えることができます

ここが正常に終わるとonPostExecuteが処理されます
ここでもUIの処理ができるので、表示してあるダイアログを消したり、テキストの編集をしたりできます

また、非同期処理中にcancelがされているとdoInBackgroundの中でisCancelで判定し終了させるか、処理がすべて終わると
onCancelledが処理されます
この中でもダイアログを閉じる処理を入れるようにすることが必要です

呼び出し方

メイン処理からAsyncTaskを呼び出す時には、以下のようにします

asyncFrag = new AsyncFrag(this);
                asyncFrag.execute(view.getId());

これだけで非同期処理の実行が可能です

終わりに

Androidで非同期処理を行うには、UIの操作ができないですが、そもそもUIと処理を密接な関係にしている処理内容がダメなんじゃないかと少し思いました
ダイアログだけだして裏でUIが絡む処理をしているとプログレスダイアログでは、くるくる回る動作をせず少しダサい気がします
出来る限り、時間のかかる処理とUIの操作は分けるように作っていきたいです



アプリ関連ニュース

お問い合わせはこちら

お問い合わせ・ご相談はお電話、またはお問い合わせフォームよりお受け付けいたしております。

tel. 06-6454-8833(平日 10:00~17:00)

お問い合わせフォーム