Activity
メソッドonSaveInstanceState()
とを使用して、状態を保存および復元しようとしていますonRestoreInstanceState()
。
問題は、onRestoreInstanceState()
メソッドに入らないことです。これがなぜであるか誰かが私に説明できますか?
Activity
メソッドonSaveInstanceState()
とを使用して、状態を保存および復元しようとしていますonRestoreInstanceState()
。
問題は、onRestoreInstanceState()
メソッドに入らないことです。これがなぜであるか誰かが私に説明できますか?
回答:
通常はで状態を復元しますonCreate()
。それを復元することも可能ですonRestoreInstanceState()
が、あまり一般的ではありません。(onRestoreInstanceState()
は後onStart()
に呼び出されますが、onCreate()
は前に呼び出されonStart()
ます。
putメソッドを使用して値を格納しますonSaveInstanceState()
。
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
icicle.putLong("param", value);
}
の値を復元しますonCreate()
。
public void onCreate(Bundle icicle) {
if (icicle != null){
value = icicle.getLong("param");
}
}
onRestoreInstanceState()
OSによって強制終了された後にアクティビティを再作成する場合にのみ呼び出されます。このような状況は次の場合に発生します。
対照的に、アクティビティBack
にいてデバイスのボタンを押すと、アクティビティはfinish()ed(つまり、デスクトップアプリケーションの終了と見なされます)となり、次にアプリを起動したときに、「フレッシュ」、つまりを押したときに意図的に終了したため、保存された状態Back
。
他の混乱の原因は、アプリが別のアプリにフォーカスを失うonSaveInstanceState()
と呼び出されますが、アプリに戻るときonRestoreInstanceState()
に呼び出されない可能性があることです。これは、元の質問で説明されているケースです。つまり、アクティビティがonRestoreInstanceState()
ほとんど「生きている」ため、他のアクティビティが前にあった期間にアクティビティが中止されなかった場合は呼び出されません。
全体として、次のドキュメントに記載されていますonRestoreInstanceState()
。
ほとんどの実装では、単にonCreate(Bundle)を使用して状態を復元しますが、初期化がすべて完了した後、またはサブクラスがデフォルトの実装を使用するかどうかを決定できるようにするために、ここで実行すると便利な場合があります。このメソッドのデフォルトの実装は、onSaveInstanceState(Bundle)によって以前にフリーズされたビューステートの復元を実行します。
私が読んだとおり:onRestoreInstanceState()
サブクラス化Activity
していない限りオーバーライドする理由はなく、誰かがサブクラスをサブクラス化することが期待されています。
保存した状態onSaveInstanceState()
は、後でonCreate()
メソッドを呼び出すときに使用できます。を使用してonCreate
(およびそのBundle
パラメーター)アクティビティの状態を復元します。
回避策として、アクティビティAを開始するために使用するインテントに維持したいデータを含むバンドルを保存できます。
Intent intent = new Intent(this, ActivityA.class);
intent.putExtra("bundle", theBundledData);
startActivity(intent);
アクティビティAは、これをアクティビティBに返す必要があります。アクティビティBのonCreateメソッドでインテントを取得します。
Intent intent = getIntent();
Bundle intentBundle;
if (intent != null)
intentBundle = intent.getBundleExtra("bundle");
// Do something with the data.
別のアイデアは、アクティビティーの状態を格納するリポジトリー・クラスを作成し、各アクティビティーがそのクラスを参照するようにすることです(シングルトン構造を使用することもできます)。
主なものは、あなたがに格納しない場合ということですonSaveInstanceState()
その後、onRestoreInstanceState()
呼び出されません。これが主な違いであるrestoreInstanceState()
とonCreate()
。本当に何かを保管してください。おそらくこれはあなたの問題です。
別のアクティビティがフォアグラウンドになると、onSaveInstanceStateが常に呼び出されることがわかりました。そしてonStopも同様です。
ただし、onRestoreInstanceStateが呼び出されたのは、onCreateおよびonStartも呼び出された場合のみです。また、onCreateとonStartが常に呼び出されるとは限りませんでした。
そのため、アクティビティがバックグラウンドに移動しても、Androidが常に状態情報を削除するとは限りません。ただし、安全のために状態を保存するためにライフサイクルメソッドを呼び出します。したがって、状態が削除されない場合、Androidはライフサイクルメソッドを必要としないため、それらを呼び出して状態を復元しません。
図2はこれを説明しています。
onRestoreInstanceStateが常にonSaveInstanceStateの後に呼び出される必要はありません。
注:onRestoreInstanceStateは、アクティビティが回転したとき(向きが処理されていないとき)に呼び出されるか、アクティビティを開いてから他のアプリを開いて、OSによってアクティビティインスタンスがメモリからクリアされるようにします。
ドキュメントから、保存されたインスタンスの状態を使用してアクティビティのUI状態を復元すると、次のように示されます。
onCreate()中に状態を復元する代わりに、システムがonStart()メソッドの後に呼び出すonRestoreInstanceState()の実装を選択できます。システムがonRestoreInstanceState()を呼び出すのは、復元する保存済みの状態がある場合のみなので 、バンドルがnullであるかどうかを確認する必要はありません。
IMO、これはonCreateでこれをチェックするよりも明確な方法であり、単一の責任の原則によりよく適合します。
私はこれに遭遇し、ドキュメントに私の答えがあることに気づきました:
「この関数がnull状態で呼び出されることはありません。」
私の場合、最初のインスタンス化でonRestoreInstanceStateが呼び出されなかったのはなぜかと思っていました。これは、何も保存しない場合、ビューを再構築するときに呼び出されないことも意味します。
私はそのようにすることができます(申し訳ありませんがc#ではなくjavaですが問題ではありません...):
private int iValue = 1234567890;
function void MyTest()
{
Intent oIntent = new Intent (this, typeof(Camera2Activity));
Bundle oBundle = new Bundle();
oBundle.PutInt("MYVALUE", iValue); //=> 1234567890
oIntent.PutExtras (oBundle);
iRequestCode = 1111;
StartActivityForResult (oIntent, 1111);
}
そしてあなたの活動のために
private int iValue = 0;
protected override void OnCreate(Bundle bundle)
{
Bundle oBundle = Intent.Extras;
if (oBundle != null)
{
iValue = oBundle.GetInt("MYVALUE", 0);
//=>1234567890
}
}
private void FinishActivity(bool bResult)
{
Intent oIntent = new Intent();
Bundle oBundle = new Bundle();
oBundle.PutInt("MYVALUE", iValue);//=>1234567890
oIntent.PutExtras(oBundle);
if (bResult)
{
SetResult (Result.Ok, oIntent);
}
else
SetResult(Result.Canceled, oIntent);
GC.Collect();
Finish();
}
最後に
protected override void OnActivityResult(int iRequestCode, Android.App.Result oResultCode, Intent oIntent)
{
base.OnActivityResult (iRequestCode, oResultCode, oIntent);
iValue = oIntent.Extras.GetInt("MYVALUE", -1); //=> 1234567890
}