AsyncTask.cancel(true)
内から呼び出した後、AndroidはdoInBackground()
呼び出す代わりに、を 呼び出します。しかし、ドキュメントによると:onCancelled()
onPostExecute()
このメソッドを呼び出すと、リターン
onCancelled(Object)
後にUIスレッドで呼び出されdoInBackground(Object[])
ます。このメソッドを呼び出すと、が呼び出されないことが保証さonPostExecute(Object)
れます。
Androidのバグですか?
その他の所見:
cancel(false)
どちらのスレッドからの呼び出しも、ドキュメントで指定されているとおりに機能します。cancel(true)
UIタスクからの呼び出しは、を呼び出しません。また、以下のlogcatトレースに示されてonPostExecute()
いるものをスローしません。InterruptedException
cancel(false/true)
スレッドからの呼び出しは、戻る前でも呼び出すことがありonCancelled()
ますdoInBackground()
。これは明らかに、次のように記載されているドキュメントに違反しています。
このメソッドを呼び出すと、 returnsの後
doInBackground(Object[])
にUIスレッドでonCancelled(Object)が呼び出されます。
コード: (Android2.2デバイスでテスト済み)
protected Void doInBackground(Void... params) {
Log.d(TAG, "started doInBackground()");
while (!isCancelled()) {
boolean ret = cancel(true);
Log.d(TAG, "cancel() returned: " + ret);
}
Log.d(TAG, "returning from doInBackground()");
return null;
}
Logcat出力
04-15 21:38:55.519: D/MyTask(27597): started doInBackground()
04-15 21:38:55.589: W/AsyncTask(27597): java.lang.InterruptedException
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1254)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:219)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask.get(FutureTask.java:82)
04-15 21:38:55.589: W/AsyncTask(27597): at android.os.AsyncTask$3.done(AsyncTask.java:196)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask$Sync.innerCancel(FutureTask.java:293)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask.cancel(FutureTask.java:75)
04-15 21:38:55.589: W/AsyncTask(27597): at android.os.AsyncTask.cancel(AsyncTask.java:325)
04-15 21:38:55.589: W/AsyncTask(27597): at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:31)
04-15 21:38:55.589: W/AsyncTask(27597): at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:1)
04-15 21:38:55.589: W/AsyncTask(27597): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-15 21:38:55.589: W/AsyncTask(27597): at java.lang.Thread.run(Thread.java:1096)
04-15 21:38:55.589: D/MyTask(27597): cancel() returned: true
04-15 21:38:55.589: D/MyTask(27597): returning from doInBackground()
04-15 21:38:55.659: D/MyTask(27597): onPostExecute()