onSaveInstanceState()およびonRestoreInstanceState()が正確に呼び出されるのはいつですか?


102

次の図(公式ドキュメントから)は、Androidアクティビティのよく知られたライフサイクルを示しています

ここに画像の説明を入力してください

一方、アクティビティがシステムによって破棄されると(たとえば、メモリを解放する必要があるため)、次の図に示すように、メソッドのおよびを使用してアクティビティの状態が自動的に保存および復元されることがあります(また、公式ドキュメントから):onSaveInstanceState()onRestoreInstanceState()

ここに画像の説明を入力してください

アクティビティが破棄されようとしているときに常に呼び出されるとonSaveInstanceState()限らないことを知ってます。たとえば、ユーザーが「戻る」ボタンを押したために破棄された場合、アクティビティの状態は保持されません。しかし、状態保存および復元され、onSaveInstanceState()/ onRestoreInstanceState()が呼び出された場合、正確いつ呼び出されますか?

例えば、上記の図によれば、onRestoreInstanceState()前と呼ばれるかもしれないonStart()、または後にonStart()しかしの前onResume()、または後にonResume()。同様に、にはいくつかの可能性がありonSaveInstanceState()ます。それで、彼らはいつ正確に呼ばれますか?

理想的には、アクティビティのライフサイクルの状態と、存在する場合は保存/復元の方法を示す図を組み合わせて見たいと思います。


onPause()とonStop()の間に呼び出されたonSaveInstanceState()がAndroidの公式ドキュメントから最終的な回答を得ました。
Rishi

1
@Rishiそのドキュメントへのリンクを提供していただけますか?
Luis Mendo 2017年


readアクティビティ状態の段落を保存
Rishi

私が正しいかどうか、明確にしてください
Rishi

回答:


107

ドキュメントごと:

void onRestoreInstanceState(バンドルsavedInstanceState)

このメソッドはとの間onStart()で呼び出されonPostCreate(Bundle)ます。

void onSaveInstanceState(バンドルoutState)

呼び出された場合、このメソッドは、Build.VERSION_CODES.Pで始まるプラットフォームをターゲットとするアプリケーションのonStop()の後に発生します。以前のプラットフォームバージョンを対象とするアプリケーションの場合、このメソッドはonStop()の前に発生し、onPause()の前または後に発生するかどうかについては保証されません。


1
ありがとう。ドキュメントへのリンクを提供していただけませんか?
Luis Mendo

これで、onStart()とonPostCreate()の間に他に何もないと思います。そのため、onRestoreInstanceState()はチェーンで適切に定義されています。
スティーブM

どうもありがとう。これにより問題が明確になります
Luis Mendo

1
@SteveM「それがonPause()の前または後に発生するかどうかについての保証はありません」これは、ビューにアクセスしようとすると(リストビューからのインデックスなど、保存する値を取得するため)、NullPointerExceptionsに遭遇する可能性があることを意味しますか?
ティアゴ

3
次に、データ構造をonPauseに保存し、onSaveInstanceStateおよびonRestoreInstanceStateではなくonResumeに復元することをお勧めします。
Gödel77

18

あたりとしてDOC1およびDOC2

onSaveInstanceState

Honeycombが登場する前は、アクティビティは一時停止されるまで強制終了とは見なされませんでした。つまり、onSaveInstanceState()がonPause()の直前に呼び出されていました。ただし、Honeycomb以降、アクティビティは停止された後にのみ強制終了可能と見なされます。つまり、onSave()は、onPause()の直前ではなく、onStop()の前に呼び出されるようになります。

onRestoreInstanceState

このメソッドは、アクティビティが以前に保存された状態から再初期化されているときに、onStart()とonPostCreate(Bundle)の間で呼び出されます。


さまざまなAndroidバージョンでシナリオを説明する方法が気に入った
Jimit Patel

14

既に投稿されている回答に加えて、Android Pには次のような微妙な変更が導入されています。

void onSaveInstanceState(Bundle outState)

呼び出された場合、このメソッドが発生しますAFTER onStop()で始まるプラットフォームターゲットとするアプリケーションのためのPを。以前のプラットフォームバージョンを対象とするアプリケーションの場合、このメソッドは前onStop()に発生し、前または後に発生するかどうかについては保証されませんonPause()

出典:docs

この変更が導入された理由に関して、ここに答えがあります:

...したがって、アプリケーションはフラグメントトランザクションを安全に実行onStop()でき、永続的な状態を後で保存できます。

出典:docs


こんにちは、素晴らしいコメント。Pをターゲットにしているが、より低いAPIで実行されるアプリの動作を知っていますか?下位のAPIを対象とするアプリと同じですか、それともAPI全体で一貫していて、「対象API」の動作を維持しますか?
Filipkowicz

@Filipkowicz、Do you know how will behave app that target P but runs on lower api?アプリがMで実行されている限り、このデバイスのAndroidのバージョンにはPで導入された変更が含まれていません。つまり、ターゲットを指定しているかどうかに関係Pなく、表示されませんpre-Pデバイスでは異なります。これがあなたの質問に答えることを願っています。
アジズベキアン

この答えを読んだ後、今日はとてもリラックスしました。UdacityでAndroidの無料コースを行っていて、レッスン5の演習8でonStopメソッドとonDestroyメソッドをそこに含めるべきではないという古いバージョンのチュートリアルがまだ残っているためです。表示されたtextView。しかし、それが古いバージョンのandroidの場合であることを知りませんでした。アプリケーションをandroid pieで実行していて、textViewでonStopメソッドを取得していました。どうもありがとうございます。やっと気持ちいい。
Sandhu

6

これは、onSaveInstanceState(バンドル)の追加情報です。

ドキュメントから

このメソッドを、アクティビティがバックグラウンドに置かれているとき、または破棄の途中であるときに常に呼び出されるonPause()、または破棄の前に呼び出されるonStop()などのアクティビティライフサイクルコールバックと混同しないでください。このメソッドではなくonPause()およびonStop()が呼び出されたときの1つの例は、ユーザーがアクティビティBからアクティビティAに戻ったときです。BでonSaveInstanceState(Bundle)を呼び出す必要はありません。その特定のインスタンスは復元されないためです。なので、システムはそれを呼び出さないようにします。onPause()が呼び出され、onSaveInstanceState(Bundle)が呼び出されない場合の例は、アクティビティAの前にアクティビティBが起動された場合です。 Aのユーザーインターフェイスの状態はそのまま残ります。

したがって、これはデフォルトの実装です。

デフォルトの実装では、IDを持つ階層内の各ビューでonSaveInstanceState()を呼び出し、現在フォーカスされているビューのIDを保存することで、インスタンスごとのほとんどのUI状態を処理します(すべてがonRestoreInstanceState(Bundle))のデフォルト実装。このメソッドをオーバーライドして、個々のビューでキャプチャされていない追加情報を保存する場合は、デフォルトの実装を呼び出す必要があります。そうでない場合は、各ビューの状態をすべて自分で保存する準備をしてください。


0
String activityState;
@Override 
public void onCreate(Bundle savedInstanceState) {
// call the super class onCreate to complete the creation of activity like 
// the view hierarchy 
super.onCreate(savedInstanceState);

// recovering the instance state 
if (savedInstanceState != null) {
     activityState = savedInstanceState.getString(STATE_KEY);
 } 

   setContentView(R.layout.main_activity);
   mTextView = (TextView) findViewById(R.id.text_view);
} 

//このコールバックは、以前に// SaveSaveInstanceState()を使用して保存された保存済みインスタンスがある場合にのみ呼び出されます。onCreate()でいくつかの状態を復元しますが、オプションで//他の状態をここで復元できます。// savedInstanceState Bundleは、onCreate()で使用されるものと同じです。

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) {
 mTextView.setText(savedInstanceState.getString(STATE_KEY));
  } 


// invoked when the activity may be temporarily destroyed, save the instance 
//state here 
//this method will be called before onstop

@Override 
 public void onSaveInstanceState(Bundle outState) {
    outState.putString(STATE_KEY, activityState);

    // call superclass to save any view hierarchy 
    super.onSaveInstanceState(outState);
} 

すみません、save / restoreメソッドが正確に呼び出されたとき、これはどのようにして質問答えますか?
Luis Mendo 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.