Android:没有从活动中调用 onSaveInstanceState
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12793069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: onSaveInstanceState not being called from activity
提问by Bharath
I have an Activity A which calls Activity B. In Activity B, when i click on a button, finish() is called, which in turn calls onDestroy() of Activity B and returns to activity A.
我有一个调用 Activity B 的 Activity A。在 Activity B 中,当我单击一个按钮时,finish() 被调用,它依次调用 Activity B 的 onDestroy() 并返回到活动 A。
According to android documentation, Before onDestroy is called, onSaveInstanceState(Bundle bundle) will be called, where i do the following.
根据android文档,在调用onDestroy之前,将调用onSaveInstanceState(Bundle bundle),我执行以下操作。
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
System.out.println("Saving webview state");
Log.d(TAG, "In onsave");
wv.saveState(outState);
}
and the next time Activity B is started from Activity A,
下次活动B从活动A开始时,
in the oncreate(), i do the following:
在 oncreate() 中,我执行以下操作:
onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(savedInstanceState != null){
//restore webview
}else {
// code
}
}
However, before calling onDestroy in Activity B, The onSaveInstanceState method is never called. any help on this will be greatly appreciated.
但是,在Activity B 中调用onDestroy 之前,从未调用过onSaveInstanceState 方法。对此的任何帮助将不胜感激。
EDIT: if this is not possible. Please let me know if there is a way to store webview state
编辑:如果这是不可能的。请让我知道是否有办法存储 webview 状态
采纳答案by Marcin S.
Please notice that onRestoreInstanceState()
is called when activity is recreated but only if:
请注意,onRestoreInstanceState()
在重新创建活动时会调用它,但前提是:
it was killed by the OS. "Such situation happen when:
它被操作系统杀死了。“这种情况发生在:
- orientation of the device changes (your activity is destroyed and recreated)
- there is another activity in front of yours and at some point the OS kills your activity in order to free memory (for example). Next time when you start your activity
onRestoreInstanceState()
will be called."
- 设备的方向发生变化(您的活动被破坏并重新创建)
- 您前面还有另一个活动,并且在某些时候操作系统会终止您的活动以释放内存(例如)。下次开始活动时
onRestoreInstanceState()
将被调用。”
So if you are in your activity and you hit Back buttonon the device, your activity is finish()
ed and next time you start your app it is started again (it sounds like re-created, isn't it?) but this time without saved statebecause you intentionally exited it when you hit Back button.
所以如果你在你的活动中并且你在设备上点击了返回按钮,你的活动被finish()
ed 并且下次你启动你的应用程序时它会再次启动(听起来像是重新创建,不是吗?)但这次没有保存状态,因为您在点击“返回”按钮时有意退出了它。
回答by Pawe? Szczur
I had a similar situation. It was clearly a dev bug. I've overridden the wrong method:
我也有类似的情况。这显然是一个开发错误。我覆盖了错误的方法:
public void onSaveInstanceState(Bundle outState,
PersistableBundle outPersistentState)
Instead a correctone:
取而代之的是一个正确的:
protected void onSaveInstanceState(Bundle outState)
回答by fangmobile.com
See the doc here: http://developer.android.com/reference/android/app/Activity.html
请参阅此处的文档:http: //developer.android.com/reference/android/app/Activity.html
Note that it is important to save persistent data in
onPause()
instead ofonSaveInstanceState(Bundle)
because the latter is not part of the lifecycle callbacks, so will not be called in every situation as described in its documentation.
请注意,重要的是将持久数据保存在
onPause()
而不是onSaveInstanceState(Bundle)
因为后者不是生命周期回调的一部分,因此不会在其文档中描述的所有情况下调用。
The documentation of onSaveInstanceStatemethod says,
onSaveInstanceState方法的文档说,
Do not confuse this method with activity lifecycle callbacks such as
onPause()
, which is always called when an activity is being placed in the background or on its way to destruction, oronStop()
which is called before destruction. One example of whenonPause()
andonStop()
is called and not this method is when a user navigates back from activity B to activity A: there is no need to callonSaveInstanceState(Bundle)
on B because that particular instance will never be restored, so the system avoids calling it. An example whenonPause()
is called and notonSaveInstanceState(Bundle)
is when activity B is launched in front of activity A: the system may avoid callingonSaveInstanceState(Bundle)
on activity A if it isn't killed during the lifetime of B since the state of the user interface of A will stay intact.
不要将此方法与 Activity 生命周期回调(例如 )混淆
onPause()
,它总是在 Activity 被放置在后台或销毁的途中onStop()
被调用,或者在销毁之前被调用。当一个例子onPause()
,并onStop()
没有必要要求:被称为,而不是这种方法是当用户离开活动B回活性的onSaveInstanceState(Bundle)
对B,因为该特定实例将永远不会被恢复,因此系统避免了调用它。一个何时onPause()
被调用而不是被调用的例子onSaveInstanceState(Bundle)
是当活动 B 在活动 A 之前启动时:onSaveInstanceState(Bundle)
如果活动 A 在 B 的生命周期内没有被杀死,系统可能会避免调用活动 A,因为 A 的用户界面的状态将保持不变.
try this:
尝试这个:
@Override
public void onPause(){
System.out.println("Saving webview state");
Log.d(TAG, "In onsave");
wv.saveState(outState);
super.onPause();
}
and
@Override
public void onResume(){
//restore webview
}
I am not sure what is the purpose of that if statement, but try this and see what happens.
我不确定那个 if 语句的目的是什么,但试试这个,看看会发生什么。
回答by aamit915
Eventually you're going to have to write the the back/history to persistent storage. In the case of the device being shut down as one example, as well as avoiding a contrived (in my opinion) example where you call onSaveInstanceState
in onPause
(what you'll need to do to get the bundle you want passed into onRestoreInstanceState
which you can then pass into restoreState
).
最终,您将不得不将背景/历史写入持久存储。在设备的情况下被关闭作为一个例子,以及避免一个人为的(在我看来),例如当你调用onSaveInstanceState
在onPause
(你需要做的就是你想通过捆绑成什么样onRestoreInstanceState
,你可以再传给成restoreState
)。
Therefore, besides reconsidering your design (if the user closed your application and you're not making a browser, do they really want to keep the same history?), you should look up SharedPreferences
and how to use them.
因此,除了重新考虑您的设计(如果用户关闭了您的应用程序而您不是在制作浏览器,他们真的希望保留相同的历史记录吗?),您还应该查找SharedPreferences
并了解如何使用它们。
Unfortunately you cannot put a bundle in shared preferences, nor would I recommend trying to write the bundle via Parcelable
(it's only meant for IPC, not persistent storage). But what you can do is store all the primitives that the bundle stores. This might be contrived too, but it seems to me the only way to get permanent storage.
不幸的是,您不能将包放入共享首选项中,我也不建议尝试通过Parcelable
(它仅用于 IPC,而不是持久存储)来编写包。但是您可以做的是存储包存储的所有原语。这也可能是人为设计的,但在我看来,这是获得永久存储的唯一方法。
And then rebuild your bundle via the primitives stored in SharedPreferences, and pass that into restoreState()
. You can check the Android source code to see what webView.saveState()
actually does (I looked up the 2.1 code and it seems to write a int, a serializeable object, and then another bundle for the SSL cert. The SSL cert bundle itself is just four integers). Off the top of my head, I'd just write all the primitives you can, and then store the location (string) of the local file you write the serialized data too.
然后通过存储在 SharedPreferences 中的原语重建您的包,并将其传递到restoreState()
. 您可以检查 Android 源代码以查看webView.saveState()
实际执行的操作(我查找了 2.1 代码,它似乎编写了一个 int、一个可序列化对象,然后是另一个 SSL 证书包。SSL 证书包本身只是四个整数) . 在我的脑海中,我只想写出所有你能写的原语,然后存储你写序列化数据的本地文件的位置(字符串)。
Even if you have some ordered collection of the entire BackForward list, I'm not sure how to translate that into the goBack()
and goForward()
using those values (there's a protected method that's involved in adding items to the list but you can't access that). UNLESS you do use restoreState()
, which is why we're going to all the work to rebuild the bundle correctly.
即使您有整个 BackForward 列表的一些有序集合,我也不确定如何将其转换为goBack()
和goForward()
使用这些值(有一个受保护的方法涉及将项目添加到列表中,但您无法访问它)。除非您确实使用了restoreState()
,这就是为什么我们要全力以赴正确重建捆绑包的原因。
Seriously though, unless my search skills are abysmal (entirely possible), storing the WebView
history in places beyond where saveInstanceState/restoreInstanceState
can do your work for you doesn't seem to be a problem a lot of people have run into. I.e. not a lot of people are trying to persist the WebView history when the user explicitly closes their application, so you have to ask yourself why are YOU doing this?
不过说真的,除非我的搜索技巧很糟糕(完全有可能),否则将WebView
历史存储在saveInstanceState/restoreInstanceState
可以为您完成工作的地方之外的地方似乎并不是很多人遇到的问题。即当用户明确关闭他们的应用程序时,没有多少人试图保留 WebView 历史记录,所以你必须问自己为什么要这样做?
Apologies if there is a really easy way to persistently store this information and reload into a WebView btw!
抱歉,如果有一种非常简单的方法可以持久存储此信息并重新加载到 WebView 中,顺便说一句!
回答by ali karimifard
for call onSaveInstance
method please just use
对于调用onSaveInstance
方法,请使用
public void onSaveInstanceState(Bundle outState)
for save a value not need use
为了保存不需要使用的值
public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState)