onBackPressedの落とし穴
onKeyDownをonBackPressedに切り替えて使ってみたら、問答無用で遷移前のActivityに戻されてしまう現象に遭遇しました。正直中途半端な知識で使うのはどうかと思っていたので、内部でどのような動作をしているか少し調べてみました。
ソースコードをどんどん辿っていったところ、onBackPressedが定義されているのは、Activity.javaの内部です。同様にonKeyDownもActivity.javaにありました。
実装されていたonBackPressedは以下です。
コメントを見るだけで何やら不穏な空気が漂っていますね。とりあえず簡単な実装として、何かするためにonBackPressedをoverrideできるときは現在のActivityを終了しますとのこと。
/** * Called when the activity has detected the user's press of the back * key. The default implementation simply finishes the current activity, * but you can override this to do whatever you want. */ public void onBackPressed() { if (mActionBar != null && mActionBar.collapseActionView()) { return; } if (!mFragments.getFragmentManager().popBackStackImmediate()) { finishAfterTransition(); } }
終了処理は、finishAfterTransitionっぽいですね。Fragmentのスタックから何も取り出せないとき(addToBackStackとかしてない)にこの処理に入ります。次にfinishAfterTransitionを見てみます。
ActivityTransitionStateはActivityの遷移状況を管理しているんですかね。ソース眺めてみましたが、他のものと違って色々知識が必要なので、メソッド名の字面から判断します。
/** * Reverses the Activity Scene entry Transition and triggers the calling Activity * to reverse its exit Transition. When the exit Transition completes, * {@link #finish()} is called. If no entry Transition was used, finish() is called * immediately and the Activity exit Transition is run. * @see android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, android.util.Pair[]) */ public void finishAfterTransition() { if (!mActivityTransitionState.startExitBackTransition(this)) { finish(); } }
すべてを理解しきれたわけではありませんが、onBackPressedの行き着く先にはfinishがいることがわかりました。ちらっとonKeyDownも眺めてみましたが、実のところ、内部でonBackPressedを呼んでいたので使う際は注意が必要かもしれません。
PS Android Studioのどんどんメソッドを辿っていける機能、ソース読むときにかなり便利だということに気づきました。