AsyncTaskとBackgroundWorkerはちょっと違う

日頃、.NET FrameworkBackgroundWorkerに慣れていたため、
AsyncTaskの説明をあまり読まずに使っていたんだけど、
AsyncTask#onPostExecuteと、
BackgroundWorker#OnRunWorkerCompletedがちょっと違うっぽい。

違うと言っても、キャンセル時のお作法が異なる。
基本的にキャンセルされたかどうかチェックしながら処理をするのは共通で、
その後に呼ばれるメソッドがちょっと異なる。

BackgroundWorkerの場合

キャンセル時(BackgroundWorker#CancelAsyncが呼ばれた場合)は、
BackgroundWorker#RunWorkerCompletedイベントの中で、
キャンセルされたかどうか判定する。

AsyncTaskの場合

キャンセル時(AsyncTask#cancelが呼ばれた場合)は、onPostExecuteは呼ばれない。
その代わり、AsyncTask#onCancelledが呼ばれる。

AsyncTask#cancelの引数をtrueを設定した場合は、
InterruptedExceptionが送出される。
これは、Thread#sleepを叩き起こすのに使うみたいだけど、
自分の用途だとこれは利用しないので、
AsyncTask#cancelの引数はfalseで良さそう。

基本、AsyncTask#onCancelledは、
onPostExecuteと同じくUIスレッドで呼び出されるので、
AsyncTask#isCancelledを見て分岐する必要がなくなった代わりに、
どちらの場合でも行いたい処理は、どちらにも書く必要がある。

なんでこんなことを調べていたかというと、
AsyncTask#doInBackgroundの中で使用しているBitmapについて、
安全にBitmap#recycleを呼んで破棄したくて、
どうやって処理しようか悩んでいた。

もちろん前提条件として、
1秒も掛からないで終わるような処理ではあるんだけど、
Fragment#onDetachで終了をポーリングするとか、
いくつか方法があると思われる。

モノクロに変換するだけならいんだけど、
今後は、もう少し処理を追加したいので、
処理の途中でキャンセルできた方が良いのかもね。

おしまい。

Leave a Comment