Android の Application task の、 Activity stack に関する怪現象
開発中に起きた出来事。発生した端末はXperia。
再起動してアプリをインストールし直したら発症しなくなったので、原因は分からず。
アプリの構造
このアプリは起動したら画面Aが表示されて、暫く待つと自動的に画面Bに移る。
- ここで Home keyを押すと、A->B という画面遷移を覚えたままホーム画面に移動する。
- Homeを押さずにBack Keyを押すと画面Bは終了して、画面Aに戻る。
このアプリは通知領域にアプリケーションのアイコンを表示する。通知領域を開いてアプリケーションを選択すると、アプリケーションを再度フォアグラウンドにするためのIntentを投げる。
また、このアプリケーションには細工がしてあって、BからAに戻った場合は一度だけAを自動的に閉じるようになっている。
また、画面Bを開く際には FLAG_ACTIVITY_REORDER_TO_FRONT を指定しているため、画面Bが Activity stack に複数保持されることはない。
本来あるべき挙動
Home keyでアプリケーションをバックグラウンドに退避させた後、再度フォアグラウンドに表示する方法は3つある。まだ他にもありえなくはないが、とりあえず想定してるのはこの三つだ。
- Home key 長押しでヒストリからアプリケーションを選択する。
- ランチャからアプリケーションを開く。
- 通知領域を開いてアプリケーションを選択する。
正常な動作では、この全てでアプリケーションは単にフォアグラウンドになる。つまり画面Bが再度表示される。
怪現象
ところが正常でない挙動をすることがあった。
通知領域を開いてアプリケーションを選択した場合や、ランチャからアプリケーションを開いた場合にアプリケーションがフォアグラウンドになるのではなく、再度画面Aが表示されて、その後自動的にBに移動する。その後でBack keyでBを閉じると、このアプリの場合はAは自動的に閉じてアプリは終了するはずなのだがそうはならず、再度画面Aが表示される。
挙動の調査と推測
Activity stack に関する情報を取得するAPIは多くないのだが、ActivityManager.RunningTaskInfo でタスク中のアクティビティの数を表示すると、通知領域を開いてアプリケーションを選択した場合や、ランチャからアプリケーションを開いた場合にタスク中のアクティビティが増加しているのがわかった。
おそらくこういう流れだ。 括弧の中はStackの状態を示している。
- [ A -> B ] この状態でアプリをバックグラウンドにして
- [ A -> B -> A ] アプリを再度起動すると、新しい画面がスタックのトップに追加されてる
- [ A -> A - >B ] 新しい画面が自動的にBに遷移した際、FLAG_ACTIVITY_REORDER_TO_FRONT の影響で古いBの位置が変わる
ここでBを閉じると、Bの手前にあるAはこのアプリの仕掛で一度だけ自動的に閉じる。その結果、残った A が再度表示されてしまう。
発生条件の調査
最初は何かコードを書き間違えたか、デバッグとリリースビルドでアプリ側の挙動に違いがあるのかと思ったがどうもそうではないようだった。
同じコードを adb install で入れた場合は怪現象は発生しなかったが、SDカード等を通してadbを使わずにインストールすると怪現象が発生した。
これが正常動作なのだとしたら困るなーと思いつつ、アプリをアンインストールして端末を再起動して再度インストールし直したら、怪現象は発生しなくなった。
おそらく何かActivityManagerに刺さるようなことがあったのだと思うが、よく分からない。
感想
へんな怪現象に休日一日取られた><;
しかも端末を再起動したら直るとかもうマジ勘弁