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