先に Google が提供するクラシックな図を見てみましょう。これは Activity のライフサイクルの各段階のナビゲーション変換を直感的に示しています。
Activity クラスには 6 つの主要なコールバックがあります:onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()。
説明#
- 通常の場合、Activity は以下の順序でライフサイクル全体を経験します:onCreate ()->onStart ()->onResume ()->onPause ()->onStop ()->onDestory ()。
- onCreate (): Activity が初めて作成されるときに呼び出され、初期化などの作業を行うことができます。たとえば、Activity に必要なデータの初期化や、setContentView を呼び出してレイアウトリソースをロードすることができます。
- onRestart ():Activity が再起動していることを示します。一般的には、現在の Activity が非表示から再び表示される状態になると、onRestart が呼び出されます。これは通常、ユーザーの操作によって引き起こされる場合があります。たとえば、ユーザーがホームキーを押してデスクトップに切り替えたり、別の新しい Activity を開いた後で、ユーザーがこの Activity に戻る場合です。
- onStart (): Activity が開始されていることを示します。つまり、まもなく開始されます。この時点で Activity は表示されていますが、** まだ前面に表示されておらず、ユーザーとの対話はできません。** これは、Activity が表示されているがまだ見えないと考えることができます。
- onResume (): Activity が表示され、前面に表示され、アクティブになっています。onStart () と比較する必要があります。onStart の時点では Activity はバックグラウンドにあり、onResume の時点で Activity が前面に表示されます。
- onPause (): Activity が停止していることを示しますが、まだ表示されています。通常、直後に onStop が呼び出されますが、onPause では時間のかかる操作を行うことはできません。これは新しい Activity の表示に影響を与えます。なぜなら、onPause が完了するまで、新しい Activity の onResume は実行されないからです。
- onStop (): Activity が停止することを示しますが、表示されていません。少し重い処理を行うことができますが、時間のかかる処理は避ける必要があります。
- onDestory (): Activity が破棄されることを示します。これは Activity のライフサイクルの最後のコールバックであり、リソースの回収や最終的なリソースの解放などを行うことができます。
一般的なシナリオ#
A ページの Activity から B ページの Activity に移動し、その後 B ページの Activity を閉じて A ページの Activity に戻る場合#
- B ページの Activity を開始する場合、最初の起動時のコールバックは次のとおりです:onCreate ()->onStart ()->onResume ()
- ユーザーが B ページの Activity を開いている場合、A ページの Activity は表示されていない状態で次のコールバックが発生します:onPause ()->onStop ()
- B ページから A ページの元の Activity に戻る場合、A ページは不可視から可視状態になり、次のコールバックが発生します:onRestart ()->onStart ()->onResume ()
- バックキーを押して戻る場合、B ページの Activity のコールバックは次のとおりです:onPause ()->onStop ()->onDestory ()
- ホームキーを押してデスクトップに切り替えた後、A ページの Activity に戻る場合、コールバックは次のとおりです:onPause ()->onStop ()->onRestart ()->onStart ()->onResume ()
- finish () メソッドを呼び出した後、コールバックは次のとおりです:onDestory ()(onCreate () メソッドで呼び出される場合を例に挙げていますが、異なるメソッドでは異なるコールバックが発生する場合があります。通常、onCreate () メソッドで呼び出されます)
Activity の 3 つの実行状態#
Resumed(アクティブ状態)#
ユーザーが操作している Activity で、画面上に表示されています。
Paused(一時停止状態)#
これはあまり一般的ではない状態です。この Activity は画面上に表示されていますが、最前面の Activity ではありません。たとえば、別の非全画面または透明の Activity が Resumed 状態であり、この Activity を完全に覆い隠していない場合です。
Stopped(停止状態)#
Activity が完全に表示されなくなったとき、この Activity はまだバックグラウンドで実行され、メモリに保持されたままです。これも理解しやすいです。別の画面に移動した場合、前の画面はまだバックグラウンドで実行され、戻るボタンを押すと元の状態に戻ります。ほとんどのソフトウェアは起動時にホームボタンを押しても閉じず、この時点での Activity は Stopped 状態です。
一部のフローの分岐#
- Activity の起動:onCreate ()—>onStart ()—>onResume ()、Activity が実行状態に入ります。
- Activity がバックグラウンドに移動:現在の Activity が新しい Activity 画面に切り替わるか、ホームボタンを押してホーム画面に戻る場合: onPause ()—>onStop ()、停止状態に入ります。
- Activity が前面に戻る:onRestart ()—>onStart ()—>onResume ()、再び実行状態に戻ります。
- Activity がバックグラウンドに移動し、システムのメモリが不足している場合、システムはこのバックグラウンドの Activity を終了します(この時点でこの Activity の参照はまだタスクスタックにありますが、参照が null を指すようになります)。この Activity に再度アクセスすると、onCreate ()—>onStart ()—>onResume () が実行されます(Activity の初期化ライフサイクルが再度実行されます)。
- スクリーンロック:onPause ()->onStop ()
- スクリーンロック解除:onStart ()->onResume ()
横画面と縦画面の切り替え#
最初の場合、現在の Activity を破棄する:#
横画面と縦画面の切り替えのプロセスでは、Activity は破棄されてから再作成されるため、この状況を避ける必要があります。
以下の 2 つのコールバックがあります:
- onSaveInstanceState と onRestoreInstanceState。
- Activity が異常終了した場合、システムは onSaveInstanceState を呼び出して現在の Activity の状態を保存します。このメソッドの呼び出しは onStop の前に行われ、onPause とは特定の順序関係はありません。このメソッドは通常、Activity が異常終了した場合にのみ呼び出されます。異常終了した Activity が再作成された後、システムは onRestoreInstanceState を呼び出し、Activity が破棄されたときに onSaveInstanceState メソッドで保存された Bundle オブジェクトパラメータを同時に onRestoreInstanceState と onCreate メソッドに渡します。したがって、Activity の状態を onRestoreInstanceState メソッドで復元することができます。このメソッドの呼び出し時期は onStart の後です。onCreate と onRestoreInstanceState メソッドの違い:onRestoreInstanceState コールバックは Bundle オブジェクトが null でないことを示しますので、null チェックは必要ありません。onCreate では null チェックが必要です。onRestoreInstanceState を使用することをお勧めします。
- 簡単に言えば、このプロセスでは Activity のライフサイクルは次のようになります:onPause ()->onSaveInstanceState ()-> onStop ()->onDestroy ()->onCreate ()->onStart ()->onRestoreInstanceState->onResume ()
2 番目の場合、現在の Activity を破棄せずに、Activity のプロパティを設定する必要がある場合:#
AndroidManifest ファイルの Activity で次の属性を指定することで、横画面と縦画面の切り替え時に Activity が破棄されずに再作成されるのを防ぐことができます。
<activity
android:name=".activity.VideoDetailActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"/>
次のメソッドをコールバックすることで、横画面と縦画面の切り替え時に Activity が破棄されずに再作成されるのを防ぐことができます。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
リソースが不足した場合、Activity の優先順位の保持方法:#
- フォアグラウンドの Activity - ユーザーとの対話中の Activity で、最も優先度が高いです。
- 可視だがフォアグラウンドではない Activity - たとえば、Activity がダイアログを表示しているため、Activity は可視ですが、ユーザーとの対話はできません。
- バックグラウンドの Activity - 一時停止された Activity で、onStop が実行されています。優先度が最も低いです。