Androidでの非同期処理の必要性と実装方法

通信を必要とするアプリでは,後述の理由により非同期処理が必要になることがあり,AsyncTask クラスを用いて実装します.

非同期処理はなぜ必要なのか

アプリ内で通信を実行したとき,通信結果によって表示内容が変わる場合を考えてみます.

通信結果を表示内容に反映させるということは,同一スレッドで処理を実行している場合,通信が終了するのを待ってから画面の更新を行うことになります.

このとき,通信が終了するまで以降の処理をすべて待機させることになるので,非常に効率が悪い上にユーザーエクスペリエンスも低下するだろう,という話です.

実装

内部クラスを作る

UI を更新するクラス内で AsyncTask クラスを継承したクラスを作ります.

private class MyTask extends AsyncTask<Params, Progress, Result> {...}

無名関数で作ってもいいようです.寧ろ,トップレベルのクラスで記述するより無名関数を使うほうがメジャーかもしれません.(わからない)

AsyncTask<Params, Progress, Result> task = new AsyncTask<Params, Progress, Result>() {...};

変数の型

  • Params: 入力する引数の型 (配列)
  • Progress: 更新を記録する変数の型っぽい (onProgressUpdate() で使う)
  • Result: doInBackground() で返す変数の型

使わないところは Void で指定します.

メソッド

クラスには必ず doInBackground() メソッドが必要で,このメソッド内にバックグラウンドでの処理を書きます.

private class MyTask extends AsyncTask<Params, Progress, Result> {
    @Override
    protected Result doInBackground(Params... params) {
        // do something
        return result;
    }

    @Override
    protected void onPostExecute(Result result) {
        Log.d(TAG, "mesasge: " + String.valueOf(result));
    }
}

必須ではないですが,非同期処理の前後やその最中に実行するメソッド onPreExecute(), onProgressUpdate(), onPostExecute() も用意されています.

onProgressUpdate() は実行の進捗を使いたいときのメソッド,onPostExecute()doInBackground() で得られた結果を受け取って処理するためのメソッドです.

メインスレッド内の実装

インスタンスを作成して実行します.

MyTask task = new MyTask();
task.execute(引数1, 引数2, ...);

doInBackground()return されると onPostExecute() 内の処理に移り,メインスレッドに戻って画面を更新します.