我试图使用 onSaveInstanceState()和 onRestoreInstanceState()方法来保存和恢复 Activity的状态。
onSaveInstanceState()
onRestoreInstanceState()
Activity
问题是它从来没有进入 onRestoreInstanceState()方法。有人能解释一下为什么吗?
在 onSaveInstanceState()中保存的状态稍后在 onCreate()方法调用中可用。因此,使用 onCreate(及其 Bundle参数)来恢复活动的状态。
onCreate()
onCreate
Bundle
通常在 onCreate()中恢复状态。在 onRestoreInstanceState()中也可以恢复它,但不是很常见。(onRestoreInstanceState()在 onStart()之后调用,而 onCreate()在 onStart()之前调用。
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()在被操作系统称为 被杀了之后被称为 只有在重建的时候活性。这种情况发生在:
相比之下: 如果你在你的活动中,你点击设备上的 Back按钮,你的活动完成()(即认为它是退出桌面应用程序) ,下次你启动你的应用程序是“新鲜的”,即没有保存状态,因为你故意退出时,你点击 Back。
Back
另一个困惑的来源是,当一个应用程序失去焦点,另一个应用程序 onSaveInstanceState()被调用,但当您导航回到您的应用程序 onRestoreInstanceState()可能不会被调用。这是最初的问题中描述的情况,也就是说,如果你的活动在其他活动在前面的时期没有被杀死,那么 onRestoreInstanceState()将不会被调用,因为你的活动几乎是“活的”。
总而言之,正如 onRestoreInstanceState()的文档所述:
大多数实现将简单地使用 onCreate (Bundle)来恢复它们的 但是有时候在这里做比较方便 初始化已经完成或允许子类决定是否 使用默认实现 方法执行任何视图状态的还原 被 onSaveInstanceState (Bundle)冻结。
正如我读到的: 没有理由覆盖 onRestoreInstanceState(),除非你正在子类化 Activity,并且预计有人将子类化你的子类。
我觉得这条线很旧了。我刚才提到的另外一个例子,onSaveInstanceState()也会被调用,就是你调用 Activity.moveTaskToBack(boolean nonRootActivity)的时候。
Activity.moveTaskToBack(boolean nonRootActivity)
主要的事情是,如果你不存储在 onSaveInstanceState()然后 onRestoreInstanceState()将不会被调用。这是 restoreInstanceState()和 onCreate()之间的主要区别。确保你真的存了东西。这很可能是你的问题。
restoreInstanceState()
在我的示例中,在更改设备方向后重新构建活动时调用 onRestoreInstanceState。首先调用了 onCreate(Bundle),但是包没有我用 onSaveInstanceState(Bundle)设置的键/值。
onRestoreInstanceState
onCreate(Bundle)
onSaveInstanceState(Bundle)
紧接着,使用具有正确键/值的 bundle 调用 onRestoreInstanceState(Bundle)。
onRestoreInstanceState(Bundle)
我发现,当另一个 Activity 出现在前台时,onSaveInstanceState 总是被调用,onStop 也是如此。
但是,只有在调用 onCreate 和 onStart 时才调用 onRestoreInstanceState。
所以看起来 Android 并不总是删除状态信息,即使活动移动到后台。但是,为了安全起见,它调用生命周期方法来保存状态。因此,如果状态没有被删除,那么 Android 不会调用生命周期方法来恢复状态,因为它们并不需要。
图2 描述了这一点。
作为一种解决方案,您可以将要维护的数据存储在用于启动活动 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.
另一个想法是创建一个存储库类来存储活动状态,并让每个活动引用该类(可以使用单例结构)不过,这样做可能会带来更多的麻烦,而不是它的价值。
如果您使用 android:configChanges="orientation|screenSize"和 onConfigurationChanged(Configuration newConfig)处理活动的方向变化,则不会调用 onRestoreInstanceState()。
android:configChanges="orientation|screenSize"
onConfigurationChanged(Configuration newConfig)
我碰巧看到这个,注意到文件上有我的答案:
“此函数将永远不会以空状态调用。”
Https://developer.android.com/reference/android/view/view.html#onrestoreinstancestate (android. os. Parcelable)
在我的例子中,我想知道为什么在初始化时没有调用 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 }
不需要总是在 onSaveInstanceState 之后调用 onRestoreInstanceState。
请注意: OnRestoreInstanceState 将始终被调用,当活动被旋转(当方向未被处理)或打开您的活动,然后打开其他应用程序,以便您的活动实例被操作系统从内存中清除。
从文件 使用保存的实例状态还原活动 UI 状态可以看出:
您可以选择不在 onCreate ()期间恢复状态 实现 onRestoreInstanceState () ,系统在 OnStart ()方法。系统仅在以下情况下调用 onRestoreInstanceState () 有一个保存的状态还原,所以你不需要检查 The Bundle is null :
IMO,这比在 onCreate 上检查这个更清楚,更符合单一责任原则。