読者です 読者をやめる 読者になる 読者になる

@neiraza

2匹の怪獣が寝た後にプログラマーしてる、最近はサイバーエージェントでゼミ長もしてる僕のネタ帳

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。