lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

アクティビティの停止と再起動

アクティビティを適切に停止、再起動することは、アクティビティのライフサイクルにおいて重要なプロセスであり、これによりアプリが常に動作中であり、進捗中の作業が失われないことをユーザーが認識できるようになります。アクティビティを停止して再開させるシナリオの主な例を次に示します。

  • ユーザーが [Recent Apps] ウィンドウを開き、現在のアプリから別のアプリに切り替えると、現在フォアグラウンドにあるアプリのアクティビティが停止します。 ユーザーがホーム画面のランチャー アイコンまたは [Recent Apps] ウィンドウから復帰した場合は、アクティビティは再起動します。
  • ユーザーが新しいアクティビティを開始するアプリ内のアクションを実行します。2 番目のアクティビティが作成されると現在のアクティビティが停止します。 ユーザーが戻るボタンを選択すると、最初のアクティビティが再起動されます。
  • ユーザーが自分の携帯電話でアプリの使用中に電話を受けます。

Activity クラスでは、onStop()onRestart() の 2 つのライフサイクル メソッドが提供され、アクティビティの停止動作と再起動動作を明確に制御できます。 UI が部分的に隠されることでわかる一時停止状態とは異なり、停止状態では必ず UI が完全に表示されなくなり、ユーザーのフォーカスが別のアクティビティ(または完全に別個のアプリ)に移ります。

注: Activity インスタンスは、停止中にシステム メモリ内に保持されるため、onStop()onRestart()(さらに onStart())メソッドを実装する必要がない場合があります。 比較的単純なアクティビティの大半では、アクティビティの停止と再起動が問題なく行われるため、現行のアクションを一時停止してシステム リソースから切り離すために onPause() を使用するだけでよい場合もあります。

図 1. ユーザーがアクティビティを離れたとき、システムは onStop() を呼び出してアクティビティ(1)を停止します。 アクティビティが停止している間にユーザーが復帰した場合、システムは onRestart()(2)を呼び出し、すぐに onStart()(3)とonResume()(4)が続きます。 アクティビティを停止させるシナリオによらず、システムは onStop() を呼び出す前に、常に onPause() を呼び出すことに注意してください。

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

アクティビティは onStop() メソッドの呼び出しを受信すると表示されなくなり、ユーザーが使用していない間は必要とされないほぼすべてのリソースが解放されます。 アクティビティが停止すると、システムはそのメモリを取り戻す必要がある場合に、インスタンスを破棄することがあります。 極端な場合には、システムは、アクティビティの最終段階に当たる onDestroy() コールバックを呼び出すことなく、アプリのプロセスを強制終了する場合があるため、onStop() を使用してメモリのリークを引き起こす可能性があるリソースを解放することが重要です。

onPause() メソッドが onStop() の前に呼び出されますが、データベースに情報を書き込むような、規模が大きく CPU に負荷がかかるシャットダウン操作を実行するためには onStop() を使用する必要があります。

永続ストレージに下書きのメモの内容を保存する onStop() の実装の例を次に示します。

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

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    getContentResolver().update(
            mUri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
            );
}

アクティビティが停止すると、Activity オブジェクトはメモリに常駐し、アクティビティが再開したときに再び呼び出されます。 再開状態に導くいずれかのコールバック メソッドの間に作成されたコンポーネントを再初期化する必要はありません。 また、レイアウト内の各 View の現在の状態が追跡されます。そのため、ユーザーが EditText ウィジェットにテキストを入力した場合、その内容が保持されるので、それを保存、復元する必要はありません。

注: 停止状態のアクティビティがシステムによって破棄された場合でも、依然として Bundle (ひとまとまりのキー値のペア)の View オブジェクト(EditText のテキストなど)の状態を保持し、ユーザーがアクティビティの同じインスタンスに復帰した場合には、それらを復元します(次のレッスンでは、アクティビティが破棄され、再作成された場合に、その他の状態データを保存するために Bundle を使用する方法を詳細に説明します)。

アクティビティを開始 / 再起動する

アクティビティが停止状態からフォアグラウンドに復帰したとき、 onRestart() の呼び出しを受信します。システムはまた、アクティビティが表示される(再起動または新規作成された場合)たびに onStart() メソッドを呼び出します。 ただし、onRestart() メソッドはアクティビティが停止状態から再開する場合にのみ呼び出されるため、アクティビティが以前に停止したが破棄されていない場合にのみ必要となる可能性がある、特別な復旧作業を実行するためにこれを使用できます。

多くの場合、アプリがアクティビティの状態を復元するために onRestart() の使用が必要となることはないため、一般的な多くのアプリに適用されるこのメソッドに関するガイドラインはありません。 ただし、onStop() メソッドは、基本的にアクティビティのすべてのリソースをクリーンアップするため、アクティビティが再起動した際には再インスタンス化する必要があります。 また、アクティビティが新規に作成されたとき(アクティビティの既存のインスタンスがない場合)にも、インスタンス化する必要があります。 このような理由から、onStop() メソッドに対応するものとして、通常は onStart() コールバック メソッドを使用する必要があります。なぜなら、アクティビティを作成したときと停止状態からアクティビティを再開したときの両方において、システムが onStart() を呼び出すからです。

たとえば、ユーザーが復帰まで長時間アプリから離れている可能性があるため、onStart() メソッドは、必要なシステム機能が有効になっているかを確認する場合に有用です。

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

    // The activity is either being restarted or started for the first time
    // so this is where we should make sure that GPS is enabled
    LocationManager locationManager =
            (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

    if (!gpsEnabled) {
        // Create a dialog here that requests the user to enable GPS, and use an intent
        // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
        // to take the user to the Settings screen to enable GPS when they click "OK"
    }
}

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

    // Activity being restarted from stopped state
}

システムがアクティビティを破棄する場合は、Activity に対して onDestroy() メソッドが呼び出されます。 通常、onStop() を使用してリソースのほとんどを解放している可能性があるため、onDestroy() の呼び出しを受信する時点では、大抵のアプリでは必要な作業は少なくなっています。 このメソッドは、メモリリークにつながる可能性を持つリソースを一掃する最後のチャンスであるため、付加的なスレッドが破棄され、さらにメソッドのトレースのような長時間実行するその他のアクションも停止するようにする必要があります。