元ネタはこちら。正確には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上で作ったソースをそのまま持って来てあっさり動くと思ってるとダメなケースがあると。使い方の問題でもあるのだけど。
コメント