Join us on the livestream at Android Dev Summit on 7-8 November 2018, starting at 10AM PDT!

アクティビティの一時停止と再開

通常のアプリの使用中、アプリがフォーカスを失う場合があり、その結果アクティビティが一時停止します。 たとえば、アプリがマルチ ウィンドウ モードで実行されているとき、フォーカスを取得しているアプリは常に 1 つだけで、システムは他のすべてのアプリを一時停止します。 同様に、半透明のアクティビティが開くと(ダイアログのスタイルなど)、以前のアクティビティは一時停止します。 そのアクティビティは、まだ部分的に表示されていても、現在フォーカスされているアクティビティではない状態である限り、一時停止状態が維持されます。

ただし、アクティビティが完全に隠され、表示されなくなった場合は、停止します(これについては次のレッスンで説明します)。

アクティビティが一時停止状態に入ると、システムは Activity 上で onPause() メソッドを呼び出します。これにより、一時停止中は継続させるべきではない進行中のアクションを停止させたり、ユーザーがアプリを離れたままになった場合に備えて保存する必要のある情報をすべて保持したりできるようになります。 ユーザーが一時停止状態からアクティビティに復帰した場合は、システムはアクティビティを再開し、 onResume() メソッドを呼び出します。

注: システムがアクティビティの onPause() メソッドを呼び出すと、システムは、アクティビティが一時停止され、ユーザーがフォーカスをアクティビティに戻す可能性があること、またはアプリがマルチ ウィンドウ モードで実行されていることを示す場合があります。 ただし、このメソッドの呼び出しは、ユーザーがアクティビティを離れていることを最初に示すものでもあります。

図 1 半透明のアクティビティによって自分のアクティビティが隠されると、システムは onPause() を呼び出し、アクティビティは一時停止の状態で待機します(1)。 一時停止中にユーザーがアクティビティに復帰した場合、システムは onResume() を呼び出します(2)。

アクティビティを一時停止する

システムがアクティビティに対して onPause() を呼び出した場合、技術的にはアクティビティはまだ部分的に表示されていることを意味しますが、ほとんどの場合は、ユーザーがアクティビティを離れていて、ほどなく停止状態になる兆候を示しています。 通常、以下を行う場合には、onPause() コールバックを使用する必要があります。

  • アクティビティが表示されるか確認して、表示されない場合は、CPU を消費する可能性のあるアニメーションまたは他の進行中のアクションを停止する。 Android 7.0 以降は、一時停止したアプリはマルチ ウィンドウ モードで実行される可能性があることに注意してください。 この場合、アニメーションや動画の再生を停止するのは好ましくないでしょう。
  • ユーザーがアクティビティを離れた場合にも変更が永続的に保存されると期待するような場合(メールの下書きなど)でのみ、未保存の変更をコミットする。
  • 放送用レシーバーなどのシステム リソース、(GPS などの)センサー処理や、アクティビティが一時停止され、ユーザーが必要としない間にバッテリー寿命に影響を与える可能性があるすべてのリソースを解放する。

たとえば、アプリケーションが Camera を使用する場合、 onPause() メソッドは、リソースの解放に適した手段です。

@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first

    // Release the Camera because we don't need it when paused
    // and other activities might need to use it.
    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }
}

一般的には、(フォームに入力された個人情報などの)ユーザーの変更を永続的なストレージに保存する目的の場合には、onPause() の使用は避ける必要があります。 特定のユーザーが(メールの下書きのように)変更の自動保存を期待していると確信できる場合のみ、onPause() の期間内に永続的なストレージにユーザーの変更を保持する必要があります。ただし、onPause() メソッド中は、データベースへの書き込みなど、CPU に高負荷をかける処理は避けてください。それによって、次のアクティビティへの表示の遷移が遅れるおそれがあります(代わりにonStop() メソッドで、高負荷処理のシャットダウン操作を実行してください)。

onPause() メソッドは、実行する処理の量をなるべく抑えてシンプルなものにしてください。アクティビティが実際に停止した場合に、ユーザーが次の移動先へ迅速に遷移できるようにするためです。

注: アクティビティが一時停止されると、Activity インスタンスはメモリに常駐し、アクティビティが再開されたときに再び呼び出されます。再開状態に導くいずれかのコールバック メソッドの間に作成されたコンポーネントを再初期化する必要はありません。

アクティビティを再開する

ユーザーが一時停止状態からアクティビティを再開した場合、システムは、onResume() メソッドを呼び出します。

新規に作成された場合を含め、アクティビティがフォアグラウンドに表示されるたびに、システムがこのメソッドを呼び出すことに注意してください。 したがって、onResume() メソッド中に解放したコンポーネントの初期化、およびアクティビティが再開状態になるたびに発生するその他の初期化(アニメーションの開始や、アクティビティがユーザーのフォーカスを取得したときにのみ使用されるコンポーネントの初期化など)を実行するように、onPause() を実装する必要があります。

onResume() に関する次の例は、上記の onPause() に関する例に対応するものであり、アクティビティが一時停止したときに解放されたカメラ機能を初期化します。

@Override
public void onResume() {
    super.onResume();  // Always call the superclass method first

    // Get the Camera instance as the activity achieves full user focus
    if (mCamera == null) {
        initializeCamera(); // Local method to handle camera init
    }
}