onSaveInstanceState() 和 onRestoreInstanceState()
我正在尝试使用方法 onSaveInstanceState()
和 onRestoreInstanceState()
保存和恢复 Activity
的状态。
问题是它永远不会进入 onRestoreInstanceState()
方法。谁能向我解释这是为什么?
I'm trying to save and restore the state of an Activity
using the methods onSaveInstanceState()
and onRestoreInstanceState()
.
The problem is that it never enters the onRestoreInstanceState()
method. Can anyone explain to me why this is?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
通常您会在
onCreate()
中恢复状态。也可以在onRestoreInstanceState()
中恢复它,但并不常见。 (onRestoreInstanceState()
在onStart()
之后调用,而onCreate()
在onStart()
之前调用。使用 put 方法在
onSaveInstanceState()
中存储值:并在
onCreate()
中恢复值:Usually you restore your state in
onCreate()
. It is possible to restore it inonRestoreInstanceState()
as well, but not very common. (onRestoreInstanceState()
is called afteronStart()
, whereasonCreate()
is called beforeonStart()
.Use the put methods to store values in
onSaveInstanceState()
:And restore the values in
onCreate()
:onRestoreInstanceState()
仅在重新创建 Activity 被操作系统杀死后调用。这种情况发生在以下情况:相反:如果您在 Activity 中并点击设备上的
后退
按钮,则您的 Activity 将完成(即,将其视为退出桌面应用程序),并且下次启动应用程序时“全新”启动,即没有保存状态,因为您在点击返回
时有意退出它。另一个令人困惑的原因是,当一个应用程序失去焦点到另一个应用程序时,
onSaveInstanceState()
会被调用,但当您导航回您的应用程序时,onRestoreInstanceState()
可能不会被调用。这是原始问题中描述的情况,即,如果您的活动在其他活动处于前面的期间没有被终止,则不会调用 onRestoreInstanceState() ,因为您的活动几乎是“活动的”。总而言之,正如
onRestoreInstanceState()
文档中所述:据我阅读:没有理由重写
onRestoreInstanceState()
除非您子类化Activity
并且预计有人会子类化您的子类。onRestoreInstanceState()
is called only when recreating activity after it was killed by the OS. Such situation happen when:In contrast: if you are in your activity and you hit
Back
button on the device, your activity is finish()ed (i.e. think of it as exiting desktop application) and next time you start your app it is started "fresh", i.e. without saved state because you intentionally exited it when you hitBack
.Other source of confusion is that when an app loses focus to another app
onSaveInstanceState()
is called but when you navigate back to your apponRestoreInstanceState()
may not be called. This is the case described in the original question, i.e. if your activity was NOT killed during the period when other activity was in frontonRestoreInstanceState()
will NOT be called because your activity is pretty much "alive".All in all, as stated in the documentation for
onRestoreInstanceState()
:As I read it: There is no reason to override
onRestoreInstanceState()
unless you are subclassingActivity
and it is expected that someone will subclass your subclass.您在
onSaveInstanceState()
中保存的状态稍后可在onCreate()
方法调用中使用。因此,请使用onCreate
(及其Bundle
参数)来恢复 Activity 的状态。The state you save at
onSaveInstanceState()
is later available atonCreate()
method invocation. So useonCreate
(and itsBundle
parameter) to restore state of your activity.从文档 使用保存的实例状态恢复 Activity UI 状态 如下所示:
IMO,这比在 onCreate 中检查这一点更清晰,并且更符合单一责任原则。
From the documentation Restore activity UI state using saved instance state it is stated as:
IMO, this is more clear way than checking this at onCreate, and better fits with single responsiblity principle.
最主要的是,如果您不存储在
onSaveInstanceState()
中,那么onRestoreInstanceState()
将不会被调用。这是restoreInstanceState()
和onCreate()
之间的主要区别。确保你确实储存了一些东西。这很可能是你的问题。The main thing is that if you don't store in
onSaveInstanceState()
thenonRestoreInstanceState()
will not be called. This is the main difference betweenrestoreInstanceState()
andonCreate()
. Make sure you really store something. Most likely this is your problem.作为解决方法,您可以将包含要维护的数据的包存储在用于启动活动 A 的 Intent 中。
活动 A 必须将其传递回活动 B。您将在活动 B 的 onCreate 方法中检索该意图。
另一个想法是创建一个存储库类来存储活动状态,并让每个活动引用该类(可以使用单例结构)。不过,这样做可能会带来更多麻烦。
As a workaround, you could store a bundle with the data you want to maintain in the Intent you use to start activity A.
Activity A would have to pass this back to Activity B. You would retrieve the intent in Activity B's onCreate method.
Another idea is to create a repository class to store activity state and have each of your activities reference that class (possible using a singleton structure.) Though, doing so is probably more trouble than it's worth.
我发现当另一个Activity来到前台时,onSaveInstanceState总是被调用。 onStop 也是如此。
但是,只有当 onCreate 和 onStart 也被调用时,onRestoreInstanceState 才会被调用。并且,onCreate 和 onStart 并不总是被调用。
因此,即使 Activity 移至后台,Android 也并不总是删除状态信息。但是,为了安全起见,它调用生命周期方法来保存状态。因此,如果状态未被删除,则 Android 不会调用生命周期方法来恢复状态,因为不需要它们。
图 2 对此进行了描述。
I found that onSaveInstanceState is always called when another Activity comes to the foreground. And so is onStop.
However, onRestoreInstanceState was called only when onCreate and onStart were also called. And, onCreate and onStart were NOT always called.
So it seems like Android doesn't always delete the state information even if the Activity moves to the background. However, it calls the lifecycle methods to save state just to be safe. Thus, if the state is not deleted, then Android doesn't call the lifecycle methods to restore state as they are not needed.
Figure 2 describes this.
我认为这个线程已经很老了。我只是提到另一种情况,当你调用
Activity.moveTaskToBack(boolean nonRootActivity)
时,onSaveInstanceState()
也会被调用。I think this thread was quite old. I just mention another case, that
onSaveInstanceState()
will also be called, is when you callActivity.moveTaskToBack(boolean nonRootActivity)
.如果您使用
android:configChanges="orientation|screenSize"
和onConfigurationChanged(Configuration newConfig)
处理 Activity 的方向更改,则onRestoreInstanceState()
将不会称为。If you are handling activity's orientation changes with
android:configChanges="orientation|screenSize"
andonConfigurationChanged(Configuration newConfig)
,onRestoreInstanceState()
will not be called.onRestoreInstanceState 不一定总是在 onSaveInstanceState 之后调用。
注意 :
当活动旋转(未处理方向时)或打开您的活动然后打开其他应用程序时,onRestoreInstanceState 将始终被调用,以便操作系统从内存中清除您的活动实例。
It is not necessary that onRestoreInstanceState will always be called after onSaveInstanceState.
Note that :
onRestoreInstanceState will always be called, when activity is rotated (when orientation is not handled) or open your activity and then open other apps so that your activity instance is cleared from memory by OS.
就我而言,当更改设备方向后重建活动时,会调用
onRestoreInstanceState
。首先调用了onCreate(Bundle)
,但该包没有我使用onSaveInstanceState(Bundle)
设置的键/值。紧接着,使用具有正确键/值的包调用
onRestoreInstanceState(Bundle)
。In my case,
onRestoreInstanceState
was called when the activity was reconstructed after changing the device orientation.onCreate(Bundle)
was called first, but the bundle didn't have the key/values I set withonSaveInstanceState(Bundle)
.Right after,
onRestoreInstanceState(Bundle)
was called with a bundle that had the correct key/values.我刚刚遇到这个问题,并注意到文档中有我的答案:
“这个函数永远不会以空状态调用。”
https://developer.android.com/参考/android/view/View.html#onRestoreInstanceState(android.os.Parcelable)
就我而言,我想知道为什么 onRestoreInstanceState 在初始实例化时没有被调用。这也意味着,如果您不存储任何内容,那么当您重建视图时就不会调用它。
I just ran into this and was noticing that the documentation had my answer:
"This function will never be called with a null state."
https://developer.android.com/reference/android/view/View.html#onRestoreInstanceState(android.os.Parcelable)
In my case, I was wondering why the onRestoreInstanceState wasn't being called on initial instantiation. This also means that if you don't store anything, it'll not be called when you go to reconstruct your view.
我可以这样做(抱歉,它是 c# 不是 java,但这不是问题...):
获得结果
并且在您的活动中最终
I can do like that (sorry it's c# not java but it's not a problem...) :
AND IN YOUR ACTIVITY FOR RESULT
FINALLY