元ネタはこちら。正確にはAPI level 1113以上から違うらしい。
API LEVEL 11以上のAsyncTaskの振る舞いについて - Google グループ
お試しソース。名前とか超適当なのはご勘弁を。
package net.swingingblue.andorid.asynctaskics;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class AsyncTaskIcsActivity extends Activity {
private static final String LOG_TAG = "AsyncTaskIcsSample";
private AsyncTask<Void, Void, Void> task1 = new SampleAsyncTask();
private AsyncTask<Void, Void, Void> task2 = new SampleAsyncTask2();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
task1.execute();
task2.execute();
}
});
}
private class SampleAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
Log.d(LOG_TAG, "SampleAsyncTask#doInbackground entered.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(LOG_TAG, "SampleAsyncTask#doInbackground go out.");
return null;
}
}
private class SampleAsyncTask2 extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
Log.d(LOG_TAG, "SampleAsyncTask2#doInbackground entered.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(LOG_TAG, "SampleAsyncTask2#doInbackground go out.");
return null;
}
}
}
結果。タイムスタンプとスレッド番号に着目。
Gingerbread(API level 10)
01-24 17:39:21.384 340 349 D AsyncTaskIcsSample: SampleAsyncTask#doInbackground entered.
01-24 17:39:21.424 340 350 D AsyncTaskIcsSample: SampleAsyncTask2#doInbackground entered.
01-24 17:39:22.398 340 349 D AsyncTaskIcsSample: SampleAsyncTask#doInbackground go out.
01-24 17:39:22.474 340 350 D AsyncTaskIcsSample: SampleAsyncTask2#doInbackground go out.
ICS(API level 15)
01-24 17:34:51.124 730 743 D AsyncTaskIcsSample: SampleAsyncTask#doInbackground entered.
01-24 17:34:52.179 730 743 D AsyncTaskIcsSample: SampleAsyncTask#doInbackground go out.
01-24 17:34:52.185 730 744 D AsyncTaskIcsSample: SampleAsyncTask2#doInbackground entered.
01-24 17:34:53.190 730 744 D AsyncTaskIcsSample: SampleAsyncTask2#doInbackground go out.
ふむふむ。
ICSではdoInBackground()の中でwaitとかやってたりすると、他のAsyncTaskをexecute()しても動かない、と。まぁ複数スレッドの待ち合わせにAsyncTaskは使わずにExecutors.newCachedThreadPool()とかしろってことですね。
(追記)
task1.execute();
の代わりに
task1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
とすればlevel 12以前の動作と同じになるみたい。
(追記おわり)
まぁGingerbread上で作ったソースをそのまま持って来てあっさり動くと思ってるとダメなケースがあると。使い方の問題でもあるのだけど。