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

アクティビティの再作成

アクティビティには、通常のアプリの動作によって破棄されるいくつかのシナリオがあります。たとえば、ユーザーが戻るボタンを選択したり、アクティビティが finish() を呼び出すことによって自身の破棄を知らせる場合などです。 システムはまた、現在停止していて長時間使用されていないアクティビティがある場合や、フォアグラウンドのアクティビティが多くのリソースを必要とするためにシステムがメモリを取り戻すためにバックグラウンド プロセスを停止する必要がある場合にも、アクティビティを破棄することがあります。

ユーザーが戻るを選択するか、アクティビティ自身が終了することでアクティビティが破棄されたとき、これらの動作はアクティビティの必要性がなくなったことを示すため、システムの方針として Activity インスタンスは完全に失われます。 システムの制約(通常のアプリの動作ではなく)が原因でアクティビティが破棄される場合、実際の Activity インスタンスは失われますが、アクティビティが存在していたことをシステムが記憶しているため、ユーザーがアクティビティに復帰した場合は、破棄されたときのアクティビティの状態を記述する一連の保存されたデータを使用して、アクティビティの新しいインスタンスが作成されます。 システムが以前の状態を復元するために使用する保存されたデータは、「インスタンス状態」と呼ばれ、Bundle オブジェクトに格納されたキーと値のペアの集合です。

警告: ユーザーが画面を回転させるたびに、アクティビティが破棄され、再作成されます。 画面の向きが変更されると、画面構成が変更され、アクティビティで(レイアウトなどの)代替リソースをロードする必要が生じる場合があるため、システムはフォアグラウンドのアクティビティを破棄し、再作成します。

デフォルトでは、システムは Bundle のインスタンス状態を使用して、アクティビティのレイアウトの各 View オブジェクトに関する情報を保存しています(EditText オブジェクトに入力されたテキスト値など)。 アクティビティのインスタンスが破棄され、再作成される場合、レイアウトの状態はコードを必要とすることなく以前の状態に復元されます。 ただしアクティビティには、たとえばアクティビティ内のユーザーの作業状況を追跡するメンバー変数など、復元したい情報以外のデータも含まれている場合があります。

注: Android システムがアクティビティのビューの状態を復元できるようにするためには、各ビューに固有の ID がある必要があります。この ID は android:id 属性で指定します。

アクティビティ状態についての追加データを保存するには、onSaveInstanceState() コールバック メソッドをオーバーライドする必要があります。システムは、ユーザーがアクティビティを離れようとすると、このメソッドを呼び出し、Bundle オブジェクトに渡してアクティビティが予期せずに破棄された場合に備えて保存します。 システムが後でアクティビティのインスタンスを再作成する必要がある場合は、同じ Bundle オブジェクトを onRestoreInstanceState()onCreate() の両方のメソッドに渡します。

図 2 システムがアクティビティを停止し始めると、onSaveInstanceState()(1)が呼び出されるため、Activity インスタンスを再作成する必要がある場合に備えて、保存する追加の状態データを指定できます。アクティビティが破棄され、同じインスタンスを再作成する必要がある場合、システムは(1)で定義された状態データを onCreate() メソッド(2)と onRestoreInstanceState() メソッド(3)の両方に渡します。

自分のアクティビティ状態を保存する

アクティビティが停止し始めると、システムは onSaveInstanceState() を呼び出すため、アクティビティではキー値のペアのコレクションを使用して、状態情報を保存することができます。 このメソッドのデフォルトの実装では、EditText ウィジェット内のテキストまたは ListView のスクロール位置などのアクティビティのビュー階層の状態に関する情報が保存されます。

アクティビティの追加の状態情報を保存するには、onSaveInstanceState() を実装し、Bundle オブジェクトにキー値のペアを追加する必要があります。 次に例を示します。

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
    savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

警告: デフォルトの実装でビュー階層の状態を保存できるよう、onSaveInstanceState() のスーパークラスの実装を常に呼び出す必要があります。

自分のアクティビティ状態をリストアする

以前破棄された後にアクティビティが再作成される場合、システムがアクティビティを渡した先の Bundle から、保存済みの状態を回復することができます。 onCreate()onRestoreInstanceState() のコールバック メソッドは両方とも、同じ Bundle を受け取り、これにはインスタンスの状態情報が含まれています。

onCreate() メソッドは、システムがアクティビティの新しいインスタンスを作成しているか、以前のものを復元しているかどうかに関係なく呼び出されるため、状態の Bundle を読み取る前にこれが null かどうかを確認する必要があります。 null の場合は、破棄された以前のアクティビティを復元する代わりにアクティビティの新しいインスタンスが作成されます。

onCreate() で、いくつかの状態データを復元する方法について、次に例を示します。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Restore value of members from saved state
        mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance
    }
    ...
}

onCreate() 中に状態を復元する代わりに、onStart() メソッドの後に呼び出される onRestoreInstanceState() を実装することもできます。 復元対象の保存済みの状態がある場合のみ onRestoreInstanceState() が呼び出されるため、Bundle が null であるかどうかをチェックする必要はありません。

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

警告: デフォルトの実装でビュー階層の状態を復元できるよう、onRestoreInstanceState() のスーパークラスの実装を常に呼び出す必要があります。

実行時の再起動イベント(画面が回転したときなど)によるアクティビティの再作成の詳細については、実行時の変更の処理をお読みください。