2011年04月18日

[Android] AsyncTask のバグ

AsyncTaskにバグがあると職場の同僚に聞いたのでググってみました。

http://d.hatena.ne.jp/kinneko/20100730/p9
http://amay077.posterous.com/asynctask-cancel-froyo22

症状としては、ActivityのonDestroy()でAsyncTaskのcancel()を呼ぶと、正しくonCancelled()が呼ばれずに、onPostExecute()が呼ばれてしまうということらしいです。
最初のバグ報告(?)はGoogle group(英語)に投稿されたものっぽいのですが、英語がろくに読めないこともあって、不具合の詳しい内容がわかりません…。
ちなみに、バグの修正は2.3でやるよ(やったよ?)ということのようです。

そうなると、2.2までのAsyncTaskを使ったアプリはそれを回避する方法を考慮した作りにしなければなりません。
が、やっぱり詳しい内容がよくわかっていません…。
発生条件はonDestroy()でcancel()を呼んだときだけなのか。onPause()で呼んだら本当に問題ないのか。
回避方法としては、それを考慮しておけばそれだけで大丈夫なのか。
探し方が悪いのかも知れませんが、バグをきちんと理解するだけの情報が得られませんでした。

そこでAsyncTaskをonCreate()で開始させ、onDestroy()でcancel()する簡単なプログラムを書いてみました。
イベントごとにLogを出力するようにしてあります。
試したのはDesire(2.2)です。

確認に使用したソース→AsyncTaskBug.zip

onDestroy()でキャンセルしたとき
04-18 00:30:28.970: VERBOSE/AsyncTaskBug(6820): Activity.onCreate:
04-18 00:30:28.970: VERBOSE/AsyncTaskBug(6820): onPreExecute:
04-18 00:30:29.990: VERBOSE/AsyncTaskBug(6820): onProgressUpdate:0
04-18 00:30:30.990: VERBOSE/AsyncTaskBug(6820): onProgressUpdate:1
04-18 00:30:31.990: VERBOSE/AsyncTaskBug(6820): onProgressUpdate:2
04-18 00:30:32.990: VERBOSE/AsyncTaskBug(6820): onProgressUpdate:3
04-18 00:30:33.990: VERBOSE/AsyncTaskBug(6820): onProgressUpdate:4
04-18 00:30:35.000: VERBOSE/AsyncTaskBug(6820): onProgressUpdate:5
04-18 00:30:35.590: VERBOSE/AsyncTaskBug(6820): Activity.onDestroy:
04-18 00:30:35.600: VERBOSE/AsyncTaskBug(6820): onCancelled
04-18 00:30:36.000: VERBOSE/AsyncTaskBug(6820): onProgressUpdate:6

…。
簡単にバグの確認ができるかと思ったのですが、きちんとキャンセルされてしまいました…。
きちんとといってもonCancelledのあとにonProgressUpdateが来ているのもおかしい気がしますが。
ついでなので、onPause()でcancel()を呼ぶよう修正して再度確認してみました。


onPause()でキャンセルしたとき
04-18 00:31:53.570: VERBOSE/AsyncTaskBug(6907): Activity.onCreate:
04-18 00:31:53.580: VERBOSE/AsyncTaskBug(6907): onPreExecute:
04-18 00:31:54.580: VERBOSE/AsyncTaskBug(6907): onProgressUpdate:0
04-18 00:31:55.580: VERBOSE/AsyncTaskBug(6907): onProgressUpdate:1
04-18 00:31:56.580: VERBOSE/AsyncTaskBug(6907): onProgressUpdate:2
04-18 00:31:57.591: VERBOSE/AsyncTaskBug(6907): onProgressUpdate:3
04-18 00:31:58.590: VERBOSE/AsyncTaskBug(6907): onProgressUpdate:4
04-18 00:31:59.590: VERBOSE/AsyncTaskBug(6907): onProgressUpdate:5
04-18 00:32:00.260: VERBOSE/AsyncTaskBug(6907): Activity.onPause:
04-18 00:32:00.290: VERBOSE/AsyncTaskBug(6907): onCancelled
04-18 00:32:00.600: VERBOSE/AsyncTaskBug(6907): onProgressUpdate:6
04-18 00:32:00.790: VERBOSE/AsyncTaskBug(6907): Activity.onDestroy:

…。
変わりません…。タイミングがちょっと早くなったくらいです…。


うーん、発生条件が違うのか…、それとも発生確率が低いのか…、はたまたDesireでは修正が適用されたものを使っているのか…。
よくわかりません。コードを書けばすぐに確認できると思っていただけに残念です。

というわけで、こんな記事にしておきながら、結局詳しいことはわかりませんでした。
この件についてどなたか教えていただけるととてもありがたいです。
バグの詳細が書かれているサイトがあればURLを教えていただけるだけでも大変助かります。
よろしくお願いします。
タグ:android AsyncTask
posted by t2low at 01:20| Android