TabActivityの罠

画面を回す(landscapeにする)とフォアグラウンドなActivityはpause→stopしタブにある全ての生成済みActivityがdestroyされる。
それだけなら良いのだが、隠れているものも含めて全てのActivityが即座に再createされる。しかし隠れているタブはresumeされない。つまり、バックグラウンドのActivityに対してonCreateが呼ばれ(下手すると永久に)onResumeが呼ばれないシチュエーションが発生しうる。
よって、onFirstResumeな処理をonCreatedに書いてはいけない。ライフサイクルにおいて可視ライフタイムはonStartからフォアグラウンドライフタイムはonResumeから始まるとされているが、onCreateの後すみやかにonStartやonResumeが呼ばれることを期待した実装はできない。少なくともTabActivityは実際にその前提を逸脱する動作をするのである。
onCreateの後、onResumeされないと、そのままonDestroy直行すら有り得るし、実際その動作もTabActivityで容易に起こる。
ドキュメントには、
onCreate()→Always followed by onStart().
onStart()→Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.
のように書かれており、つまり実装かドキュメントかどちらかが間違っている。
ただどうもこの辺りの実装は怪しい。具体的に言うとListActivity周辺がきちんと考慮された実装になっていないように見受けられる。おかげでTabActivityとListActivity(の類)の相性が猛烈に悪い。
実際、TabActivityのそれぞれのタブにExpandableListActivityとListActivityを配置してタブ切り替えと縦横回転を数回やると簡単に例外死する。ListActivityだけなら問題ないようだがExpandableListActivityと併用するとまさに即死である。
日本Androidの会に質問投げてみたのだがレスが付かなくて色々探してたら
http://code.google.com/p/android/issues/detail?id=3443
OHAの方にバグとしてissue上がってた。Activityを直継承して全部自分で実装すればいいよみたいなレスが付いているがそういう問題じゃねーだろと思う。
このような動作をするのは見たところTabActivityだけなのでとりあえずTabActivityは使わないことにした。
どちらにしても一貫して貰えないと困る。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


The reCAPTCHA verification period has expired. Please reload the page.