うきっとラボ~中卒から始めるプログラミング~

中卒のポンコツ太郎が立派なプログラマになるまでの道のり

【Android Studio】コールバックメソッドの呼ばれ方について検証してみた

はじめに

「コールバックメソッドってなに?」って思った方は、
こちらからご覧ください!
ukit-labo.hateblo.jp

では、実際にアプリを動かしながら
どのようにして各コールバックメソッドが呼ばれているのかを確認してみます。
各メソッドにログ出力を実装して、いろいろなパターンで検証してみます!

さぁ、やっていきましょう!


アプリを起動する

【検証内容】
[ホーム画面] → [アプリ起動]
ホーム画面からアプリのアイコンをタップして、アプリを立ち上げてみます。

【前提状態】
なし

【結果】
①onCreate()
②onStart()
③onResume()

~アプリ起動~

となりました。
画面の表示とログの出力はほぼ同時でした。(若干ログ出力の方が早いかな?ぐらい)
これらのメソッドが止まらずに連続して呼び出されていることがポイントですね。


アプリを終了する

【検証内容】
[アプリ起動] → [アプリ終了]
アプリを立ち上げた状態で、端末の◀ボタンを押してアプリを終了してみます

【前提状態】
Main → onResume() 状態

【結果】
①onPause()
~アプリ終了~
②onStop()
③onDestroy()

となりました。
onPause()とアプリ終了はほぼ同時でした。
ただ、onPause()が呼び出されてからonStop()が呼び出されるまでの間、体感で少しだけラグがあるような気がします。
これによって、「onPause()は画面が閉じ始めた時」「onStop()は完全に画面を閉じた時」ということがなんとなく理解できますね。


スリープ状態にする

【検証内容】
[アプリ起動] → [スリープ]
アプリを再び立ち上げると、もう一度onCreate()~onResume()が呼ばれました。
今度は端末の電源ボタンを一度押して、スリープ状態にしてみます。

【前提状態】
Main → onResume() 状態

【結果】
~画面が暗くなる~
①onPause()
②onStop()

となりました。
画面が閉じてから、メソッドが呼び出されました。
また、今回はonDestroy()が呼ばれていません。ということは、バックグラウンドでまだアクティビティは存在している、ということを表していますね。
ただ気になったのは、今回はonPause()とonStop()の間にラグはありませんでした。もしかするとアクティビティが破棄されないことや、画面を暗くすることに関係しているのかもしれません。


スリープを解除する

【検証内容】
[アプリ起動] → [スリープ] → [スリープ解除]
スリープ状態からもう一度電源ボタンを押し、復帰してみます

【前提状態】
Main → onStop() 状態

【結果】
①onRestart()
②onStart()
③onResume()
~画面が明るくなる~

となりました。
今回はスリープ実行時とは逆に、画面が表示される前に、メソッドが実行されています。
また、アプリ起動時違い、onCreate()ではなくonReStart()が呼ばれていますね。


タスクビューにする、ホーム画面に戻る

【検証結果】
これらはスリープ時と全く同じメソッドが呼ばれました。アプリに戻るときも同様でした


画面を遷移する

【検証内容】
[Main] → [Sub]
今度はアクティビティを一つ増やし、画面遷移時の動きを見てみます。
遷移後のアクティビティにも、同様にログ出力を実装しています

【前提状態】
Main → onResume() 状態
Sub → 未起動

【結果】
①Main_onPause()
②Sub_onCreate()
③Sub_onStart()
④Sub_onResume()
~遷移する~
⑤Main_onStop()

となりました。
MainのonPause()が呼ばれた後、Subの表示処理をし、遷移してからMainのonStop()が呼ばれています。
また、Mainはバックグラウンドで生きているため、onDestroy()は呼ばれていませんね。


遷移先から戻る

【検証内容】
[Main] → [Sub] → [Main]
finish()でSubActivityからMainActivityに戻ってみます。

【前提状態】
Main → onStop() 状態
Sub → onResume() 状態

【結果】
①Sub_onPause()
②Main_onRestart()
③Main_onStart()
④Main_onResume()
~画面が戻る~
⑤Sub_onStop()
⑥Sub_onDestroy()

となりました。
先ほどの遷移時と似ていますが、MainActivityの再開にはonRestart()、またfinish()でSubActivityを終了しているためSub_onDestroy()が呼ばれていますね。


遷移後にアプリを強制終了してみる

【検証内容】
[Main] → [Sub] → [アプリ終了]
MainActivityからSubActivityに遷移した後、そのままタスク一覧からアプリを終了してみます。
どんな動きになるのでしょうか。

【前提状態】
Main → onStop() 状態
Sub → onResume() 状態

【結果】
~タスク一覧画面になる~
①Sub_onPause()
②Sub_onStop()
~アプリが終了~
③Main_onDestroy()

となりました。
MainActivityのonDestroy()は呼ばれていますが、SubActivityの方は呼ばれていませんね。
このように、イレギュラーな操作があった場合、onDestroy()が呼ばれずに終了することもあるようです。


遷移後に電源を切ってみる

【検証内容】
[Main] → [Sub] → [電源OFF]
よくあるパターンとして「アプリ使用中に突然再起動された」とかですかね?
では見ていきましょう。

【前提状態】
Main → onStop() 状態
Sub → onResume() 状態

【結果】
①Sub_onPause()
②Sub_onStop()
~電源切れる~

となりました。
今回はどちらのonDestroy()も呼ばれませんでした。
端末再起動後にアプリを起動すると、予想通りonCreate()から始まりました。


MainActivity表示中に画面を回転させてみる

【検証内容】
[Main] → [横画面にする]
さて、ここで画面回転時の動きも見てみましょう!
普段何気なく使っている機能ですが、内部ではどうなっているのでしょうか?

【前提状態】
Main → onResume() 状態

【結果】
①Main_onPause()
②Main_onStop()
③Main_onDestroy()
④Main_onCreate()

⑤Main_onStart()
⑥Main_onResume()
~画面回転~

となりました。
なんと!画面を回転しただけなのにonDestoy()が呼ばれ、アクティビティが再起動していますΣ(・ω・ノ)ノ!


遷移後に画面を回転させてみる

【検証内容】
[Main] → [Sub] → [横画面にする]
SubActivityに遷移した後、画面を回転させてみます。
バックグラウンドでMainActivtyは生きているので、どうなるでしょうか。

【前提状態】
Main → onStop() 状態
Sub → onResume() 状態

【結果】
①Sub_onPause()
②Sub_onStop()
③Sub_onDestroy()
④Sub_onCreate()
⑤Sub_onStart()
⑥Sub_onResume()
~画面回転~

これまたびっくり!!再起動したのはSubActivityだけでした!!Σ(゚Д゚)
画面が回転して再起動されるのは「表示中のアクティビティだけ」なんですね~(^_^)vナルホド


遷移後に画面を回転させ、そのままMainActivityに戻ってみる

【検証】
[Sub] → [横画面にする] → [Main]
先ほどの検証でSubActivityに遷移後、画面を回転させてみました。
次はその状態のまま、finish()でMainActivityに戻ってみます。
さぁ。。。どうなる??

【前提】
Main → onStop() 状態
Sub → onResume() 状態

【結果】
①Sub_onPause()
②Main_onDestroy()
③Main_onCreate()

④Main_onStart()
⑤Main_onResume()
~画面が戻る~
⑥Sub_onStop()
⑦Sub_onDestroy()

あれ?MainのonRestart()が呼ばれていない!
画面の向きを変えずに戻った時は、Main_onRestart()が呼ばれ、アクティビティが再開していました。
しかし今回は「再開」ではなく「破棄して新規生成」されています。

ちょっと気になることがあったので、
ついでにもう一つ検証してみましょう!!!!

遷移後に画面を回転させ、また戻して、それからMainActivityに戻ってみる

【検証】
[Sub] → [横画面にする] → [縦画面にする] → [Main]
先ほどの検証で、「画面が回転した時は、遷移前の画面でもアクティビティのリセットが行われる」
という可能性が見えてきました。
じゃあ、「遷移後、一旦画面回転したけど、元の向きで戻ってきたよ」という場合は?

ささ、検証検証ぉ~!!

※「横画面→縦画面」「縦画面→横画面」どちらも同じ呼び出しなので、回転時の呼び出しは省きます!

【前提状態】
Main → onStop() 状態
Sub → onResume() 状態

【結果】
~画面をもう一度縦にした後~
①Sub_onPause()
②Main_onRestart()
③Main_onStart()
④Main_onResume()
~画面が戻る~
⑤Sub_onStop()
⑥Sub_onDestroy()

SubActivityにて画面が回転しているにも関わらず、
今度はMain_onRestart()が呼ばれています。

この結果からわかることは、

画面回転の判定は、その画面が表示された時に行われる

ということですね!
遷移先の画面でいくら回転されていようが、戻ってきたときの向きで判断しますよ~と!

これはもしかしてすごい発見ではないのか!?( ´艸`)笑


まとめ

今回の検証は以上です!
どんなときにどんなメソッドが呼ばれるのかを分かっていれば、
そこに書く処理をある程度決めることができますね(^_^)v

この機能をしっかり活かしてコードを書いていきましょう(/・ω・)/
がんばるぞー!

追記・修正

  • 2019/11/24 検証内容の追加

 「遷移後に画面を回転させ、そのままMainActivityに戻ってみる」
 「遷移後に画面を回転させ、また戻して、それからMainActivityに戻ってみる」
 を追加しました。