公式:http://developer.android.com/reference/android/os/AsyncTask.html
Javaでよく使われる非同期処理。
使われる理由としては、
・AsyncTask<Params, Progress, Result>
第1引数…メインスレッドから別スレッドに渡すパラメーターの方
※ doInBackground()の引数の型
※ 非同期処理にパラメータを渡したい場合に扱う。特になければnullを指定する
第2引数…進捗度合を表示する時に利用したい型
※ onProgressUpdate()の引数の型
※ 進捗度を計りたい場合に扱う。特になければnullを指定する
第3引数…バックグラウンド処理完了時に受け取る型
※ doInBackground()の戻り値の型
※ onPostExecute()の引数の型
※ 非同期処理からメインスレッドに結果(値)を受け取りたい時に扱う
・doInBackground()
別スレッドで実行されます。
この処理のみ必ず実装しなければいけません。
・onPreExecute()
doInBackground実行直前にメインスレッドで処理を行います。
非同期前にメインスレッドで実行したい処理を記述します。
・onProgressUpdateは()
非同期処理の進行状況をプログレスバーで表示する場合などに扱います。
doInBackgroundのfor文内で呼ぶイメージです
・onPostExecute()
doInBackground実行直後にメインスレッドで実行されます
doInBackgroundから戻り値で結果を受け取れます
※ onPreExecute() > doInBackground() > onPostExecute() の実行順で呼ばれます
onProgressUpdate()はdoInBackground()内で呼びます
※ 無名メソッドで処理する場合は、上記メソッド内で変数を扱う場合、
final修飾子を付けるかクラス変数(static)に持たせる必要があります。
・cancel(boolean)
非同期処理をキャンセルします
・onCancelled()
キャンセル後に実行されます。
例:取りあえず特にパラメータや戻り値を気にしない場合のAsynkTask
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
//非同期処理
return null;
}
}.execute();
例:パラメータ、戻り値、キャンセルを意識したAsyncTask
AsyncTask<String, Void, Number> task = new AsyncTask<String, Void, Number>() {
@Override
protected Number doInBackground(String... params) {
//非同期処理
Log.v("tag","パラメータ:"+params[0]);
int statusCode = 200;
return statusCode;//このreturnしたオブジェクトがonPostExecute()に渡される
}
@Override
protected void onPostExecute(Number resultCode) {
//非同期後の処理 メインスレッドでの処理
Log.v("tag","通信結果:"+resultCode);
}
@Override
protected void onCancelled() {
//キャンセル処理
Log.v("tag","キャンセル");
}
};
//AsyncTask実行
task.execute("POST",null,null);//ここの第一引数がdoInBackground()に渡される
//AsyncTaskキャンセル
task.cancel(true);
非同期処理をメインスレッドで待ちたい場合もあります。
例えば単体テストで非同期のテスト結果を待ちたい場合など。
そういう時に便利なのが「CountDownLatch」です。
1.カウントダウン用の引数を渡してインスタンスを生成し、非同期になんらかの形で渡します。
CountDownLatch latch = new CountDownLatch(1);
2.カウントダウンが0になるのを待ちます
latch.await();
3.非同期のコールバック内でカウントします
latch.countDown();//-1
これでlatchのプロパティが0になるとawait()後の処理が実行されます。
先ほどのAsynkTaskと組み合わせると以下のような形になります。
//非同期内で実行するためにfinal修飾子をつける
final CountDownLatch latch = new CountDownLatch(1);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
//非同期処理
latch.countDown();
return null;
}
}.execute();;
//非同期待ち
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.v("tag","完了");
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
//非同期処理
return null;
}
@Override
protected void onPostExecute(Void result) {
//非同期後のUIスレッド処理
}
}.execute(null,null,null);