AsyncTaskで非同期を実現してみますか
AndroidだとHandlerを使ったり、Serviceを使ったりするかと思うのですが、
今回はこいつも使ってみました。
先に言っちゃうと、AsyncTaskのcancelにバグあるよーとか、
Twitterで「うさミミ」な人に教えて貰ったりしたのですが、
今回はそこをチラッとだけ確認しましたが、影響でなそーなレベルでしか使ってません。
使い方だけまとめておきます。
AsyncTask
適当に継承しちゃいます。
ジェネリクスの中が「Void, Void, Void」としましたが、
ここは使う時によって変更すればOKです。
一応説明すると~
- 右端
doInBackground用の引数で可変。なので使う側では配列で受け取り。
- 真ん中
onProgressUpdate用の引数で可変。こいつも配列で受け取り。
- 左端
onPostExecute用の引数。こいつはdoInBackgroundの結果を受け取る。
public class HogeTask extends AsyncTask<Void, Void, Void> { }
んで、このクラスを実装していきます。
AsyncTaskからオーバーライドして使うものとして~
onPreExecute
ここでProgressDialogをつくってみた。
@Override protected void onPreExecute() { dialog = new ProgressDialog(context); dialog.setTitle("Please wait"); dialog.setMessage("Loading data..."); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); dialog.setCancelable(true); dialog.setOnCancelListener(this); dialog.setMax(100); dialog.setProgress(0); dialog.show(); }
doInBackground
これがメインの処理。こいつが非同期に動かしたいやつ。
@Override protected Void doInBackground(Void... params) { Hoge hoge = createhoge(); publishProgress(20); String hogeId = hoge(getApplication()).send(mAccount, mMessage); publishProgress(60); foo(hogeId); publishProgress(100); return null; }
onProgressUpdate
doInBackground内でpublishProgressを使って呼び出してゴニョゴニョ。
僕はProgressDialogの更新に使った。
@Override protected void onProgressUpdate(Integer... values) { dialog.setProgress(values[0]); }
onCancelled
ProgressDialogをdismissだけ書いてみた。
@Override protected void onCancelled() { dialog.dismiss(); }
onPostExecute
doInBackgroundが終わったら、こいつが呼ばれるので事後処理とかさせた。
@Override protected void onPostExecute(Void tmp) { onSync(mAccount); }
onCancel
DialogInterface.OnCancelListenerをHogeTask で実装してオーバーライド。
@Override public void onCancel(DialogInterface dialog) { this.cancel(true); }
Handlerとの使い分けとか、よく分かんないんだけど、
こっちはサーバーから何かダウンロードとかする時で、
非同期といいつつも、どっかに進捗バー出しつつ~みたいなのを実装しようとすると、
AsyncTaskを実装するだけで実現できるので、Handlerでテンプレ的に技が固まってない人は、
こっちのほうが楽かなーって気がする。
あんまし、使い分けって話しにはなってないけど、自己整理OK。