先日、会社でandroid 4.4にアップグレードした際に挙動がおかしくなった件があったのでメモ。
androidの画面遷移はUIスレッドなる1つのスレッドで処理が行なわれる。
そのスレッドで思い処理をしちゃうと、画面がフリーズした状態になるので、重い処理は別スレッドをしようしましょう、というのが基本。
何個か方法があるんだが、その中の1つ「AsyncTask」で嵌った。
基本的には1つしか起動しないんだけど、複数起動したい場合はexecuteOnExecutorメソッドを使用すればOK。
これにAsyncTask.THRED_POOL_EXECUTORを指定して起動する。
android 4.3までは、このAsyncTaskを何個起動しても問題なく動作してたんだけど、
4.4に上げたところ、制限がかかって動かなくなった!!
ちなみに動かなくなったデバイスはNexus10。
なぜ?と思い、AsyncTaskを複数同時(とりあえず5個)に立ち上げるプログラムを作成して実験。
以下の結果に。
-------------------------------------------------
■Nexus4
android 4.3 実機 → OK
android 4.3 エミュ → OK
android 4.4 実機 → 未実施(大事なデバイスなので上げられない。。。)
android 4.4 エミュ → NG(2個までしか動かない)
■Nexus5
android 4.4 実機 → OK
■Nexus7
android 4.3 エミュ → OK
android 4.4 エミュ → NG(2個までしか動かない)
■Nexus10
android 4.3 エミュ → OK
android 4.4 実機 → NG(3個までしか動かない)
android 4.4 エミュ → NG(2個までしか動かない)
-------------------------------------------------
とりあえず、4.4でエミュレータだと絶対ムリ。なんでだろう?設定かな。
ちなみに、スレッドを1つだけ終了すると、待ち状態の1つが動き出すので、2個(もしくは3個)の制限がかかっている模様。
で、実機だと面白くてNexus5だと正常に動く。・・・なぜ?
Nexus4も4.4にしたいんだけど、大事な審査があるのでそれまでは現状のOSでいきたいので保留。
androidのソースを見たんだけど、制限数が変わっている様子もない。
このAsyncTaskは画面が表示されている間は、画面を定期的に更新するためにずーっと起動しているんだけど、そういう使い方はよろしくないらしい。
特にスリープ状態(画面が消えた状態)になると、システムにいつ殺されるかわからないらしい。なんてことするんだandroid。。。
なので、処理を変更した。
画面(Activity)でレシーバーを作成して、Serviceから通知を送ってもらって更新するようにした。
これだとほぼ同じような処理を実現できるし、androidに殺される心配はない・・・はず。
なんだけど殺されている気がしないでもない。。。うーん、しばらく悩みそう。
とりあえず、AsyncTaskは一杯起動しちゃダメ、ということっぽい。