web-dev-qa-db-ja.com

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

次の図( 公式ドキュメント から)は、Androidアクティビティのよく知られているlifecycleを説明しています。

enter image description here

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

enter image description here

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

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

理想的には、アクティビティライフサイクルの状態と保存/復元メソッドを示す組み合わせ図(存在する場合)を見ることです。

87
Luis Mendo

ドキュメント

void onRestoreInstanceState(Bundle savedInstanceState)

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

void onSaveInstanceState(バンドルoutState)

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

90
Steve M

doc1 および doc2 に従って

onSaveInstanceState

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

onRestoreInstanceState

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

15

既に投稿された回答に加えて、Android Pにはわずかな変更が導入されています。

void onSaveInstanceState(Bundle outState)

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

ソース: docs

この変更が導入された理由については、答えは次のとおりです。

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

ソース: docs

12
azizbekian

これはonSaveInstanceState(Bundle)の追加情報です

ドキュメントから

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

だから、デフォルトの実装です。

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

5
Mahmoud Mzz
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);
} 

//このコールバックは、// onSaveInstanceState()を使用して以前に保存された保存済みインスタンスがある場合にのみ呼び出されます。 onCreate()でいくつかの状態を復元しますが、オプションで//ここで他の状態を復元できます。おそらくonStart()の完了後に使用できます。 // 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);
} 
0
parvez rafi