Android:onSaveInstanceState未从活动中调用

时间:2012-10-09 04:59:21

标签: android android-activity

我有一个活动A,它调用活动B.在活动B中,当我点击一个按钮时,调用了finish(),然后调用活动B的onDestroy()并返回活动A.

根据android文档,调用on 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);

    }

,下次从活动A开始活动B,

在oncreate()中,我执行以下操作:

onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

if(savedInstanceState != null){
//restore webview
}else {
// code
}
}

但是,在Activity B中调用onDestroy之前,永远不会调用onSaveInstanceState方法。 任何有关这方面的帮助将不胜感激。

编辑:如果这是不可能的。如果有办法存储webview状态,请告诉我

5 个答案:

答案 0 :(得分:241)

我有类似的情况。这显然是一个开发者的错误。我已经覆盖了错误的方法:

public void onSaveInstanceState(Bundle outState, 
                                PersistableBundle outPersistentState)

而是正确一个:

protected void onSaveInstanceState(Bundle outState)

答案 1 :(得分:50)

请注意,重新创建活动时会调用onRestoreInstanceState(),但仅限于:

它被操作系统杀死了。 “这种情况发生在:

  • 设备的方向发生变化(您的活动被破坏并重新创建)
  • 在你面前还有另一项活动,在某些时候,操作系统会杀死你的活动以释放内存(例如)。下次开始您的活动时,系统会调用onRestoreInstanceState()。“

因此,如果您参加了自己的活动并且点击设备上的“返回”按钮,则您的活动为finish(),下次启动应用时,它会再次启动(听起来像是重新创建,不是吗?)但是这次没有保存状态,因为当你点击Back按钮时你有意退出它。

答案 2 :(得分:6)

请参阅此处的文档: http://developer.android.com/reference/android/app/Activity.html

  

请注意,在onPause()中保存持久数据非常重要   而不是onSaveInstanceState(Bundle),因为后者不是   生命周期回调的一部分,因此不会在每个回调中调用   其文件中描述的情况。

onSaveInstanceState方法的文档说明,

  

不要将此方法与活动生命周期回调混淆,例如   onPause(),在放置活动时始终调用   在背景中或在毁灭的路上,或onStop()   在破坏之前召集。 onPause()和{。}的一个例子   调用onStop(),而不是此方法是用户导航回来的方法   从活动B到活动A:没有必要打电话   B上的onSaveInstanceState(Bundle)因为该特定实例   永远不会恢复,所以系统避免调用它。一个例子   调用onPause()而不是onSaveInstanceState(Bundle)时   当活动B在活动A前面启动时:系统可以   如果不是,请避免在活动A上调用onSaveInstanceState(Bundle)   自用户界面状态以来在B的生命周期内被杀死   A将保持完整。

试试这个:

@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
 }

我不确定if语句的目的是什么,但试试看看会发生什么。

答案 3 :(得分:3)

最终,您将不得不将后面/历史记录写入持久存储。在关闭设备的情况下,作为一个示例,以及避免在onSaveInstanceState中调用onPause的设计(在我看来)示例(您需要做什么才能获得您希望传递到onRestoreInstanceState的捆绑包,然后您可以将其传递到restoreState)。

因此,除了重新考虑您的设计(如果用户关闭您的应用程序而您没有制作浏览器,他们真的想保留相同的历史吗?),您应该查找SharedPreferences以及如何使用它们。

不幸的是,您不能在共享首选项中放置一个包,也不建议尝试通过Parcelable编写包(它仅适用于IPC,而不是持久存储)。但你可以做的是存储捆绑存储的所有原语。这也可能是人为的,但在我看来,这是获得永久存储的唯一途径。

然后通过存储在SharedPreferences中的基元重建您的包,并将其传递到restoreState()。您可以检查Android源代码以查看webView.saveState()实际执行的操作(我查找了2.1代码,它似乎编写了一个int,一个可序列化的对象,然后是另一个SSL证书包.SSL证书包本身只是四个整数)。在我的脑海中,我只需要编写所有原语,然后存储您编写序列化数据的本地文件的位置(字符串)。

即使您有整个BackForward列表的一些有序集合,我也不确定如何使用这些值将其转换为goBack()goForward()(有一个受保护的方法,它涉及添加列表中的项目,但您无法访问该项目)。除非您使用restoreState(),这就是为什么我们要正确地重建捆绑包的所有工作。

严重的是,除非我的搜索技能很糟糕(完全可能),将WebView历史存储在saveInstanceState/restoreInstanceState以外的地方可以为你工作,这似乎不是一个问题很多有人遇到过。即当用户明确关闭他们的应用程序时,很多人都没有尝试持久保存WebView历史记录,因此您必须问问自己为什么要这样做?

道歉,如果有一种非常简单的方法来持久存储这些信息并重新加载到WebView btw中!

答案 4 :(得分:0)

对于致电onSaveInstance方法,请使用

public void onSaveInstanceState(Bundle outState)

保存值不需要使用

public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState)