尽管调用onSaveInstance(),但在onCreateView()中Bundle savedInstanceState始终为null

时间:2014-10-05 01:27:09

标签: android android-fragments bundle

FragmentA托管了ActivityA。当用户从选项菜单中选择一个项目时,会启动ActivityB,其中包含FragmentB。目前,我希望通过覆盖String来保留booleanFragmentA onSaveInstanceState(),因此当用户返回FragmentA时,他们的信息会被保留

来自FragmentA的代码:

@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
    //LOGS SHOW THAT THIS IS ALWAYS CALLED WITH CORRECT VALUES
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putString("string", "example");
    savedInstanceState.putBoolean("boolean", bool);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
    View v = inflater.inflate(R.layout.fragmentA, parent, false);

    //LOGS SHOW THAT THIS IS ALWAYS NULL
    if (savedInstanceState != null)
    {
        if (savedInstanceState.getString("text") != null)
        {
            mObject.setText(savedInstanceState.getString("string"));
        }

        bool = savedInstanceState.getBoolean("boolean");
    }

    ...
}

从阅读以前与我类似的问题:

1)我决定放置代码以恢复onCreateView()中的信息,因为onCreate()并不总是被调用。 (尽管使用onCreate()中的代码进行的测试也存在同样的问题。)

2)我也没有致电setRetainInstance(true),因为这会导致Bundle savedInstanceState始终为null

3)我确保FragmentA的XML布局有一个id。此布局的各种子元素也有ID。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragmentA"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"> 

    ...
</LinearLayout>

尽管如此,Bundle savedInstanceState始终为空。我在这里缺少什么?

任何帮助表示赞赏。谢谢!

2 个答案:

答案 0 :(得分:2)

如果之前未保存任何数据,则savedInstanceState为空。要保存数据,您必须覆盖Android文档中描述的onSaveInstanceStateBundle(Bundle)方法:

  

您应该使用onPause()方法将任何持久性数据(例如用户编辑)写入存储。此外,在将活动置于这样的背景状态之前调用onSaveInstanceState(Bundle)方法,允许您将活动中的任何动态实例状态保存到给定的Bundle中,以便稍后在onCreate(Bundle)中接收需要重新创建。有关流程生命周期如何与其托管的活动相关联的详细信息,请参阅流程生命周期部分。请注意,将持久数据保存在onPause()而不是onSaveInstanceState(Bundle)中非常重要,因为后者不是生命周期回调的一部分,因此不会在其文档中描述的所有情况下调用。

More info here

答案 1 :(得分:2)

使用onPause()保存持久数据,这些数据指的是您想永久保留的数据,因此,您将其保存在SharedPreferences或{{1 }}。另一方面,Database重新训练数据,以防活动被破坏,并且您想要恢复该数据,一个好的方案是用户填写表格。您在示例中说过,您要从onSaveInstanceState导航到Activity A,然后返回Activity B,当您第一次导航时,Activity A未被销毁,它只发送到后台,所以当你返回它时,它已经存在并将被带到前台,你的值实际上应该保持不变,Activity A和{{ 1}}将不会被调用,因为Activity仍处于活动状态(尽管在设备内存不足的情况下可能会被杀死)。

测试onCreate的最佳和最快的方式是最常用的方案,方向更改,方向更改将导致活动被完全销毁并重新创建,因此允许方向更改onCreateView,在onSaveInstanceState中添加一些值并旋转设备,现在这将从头开始调用您的所有方法,Activity AsaveStateBundle,等等要使用适当的布局创建活动,您的onCreate现在不应为null。

请注意,这是假设您的应用程序处于活动状态,如果您要完全关闭应用程序但仍希望保留数据,那么请将您的信息放在onCreateViewsavedInstanceState中并在您再次启动应用程序时检索它们。

//编辑1

为了向您展示如何在应用中的任何位置存储 SharedPreferences 中的值,即使您的应用已关闭,这些值也会保持不变。 (虽然onSaveInstanceState应该足以满足您的需求,但希望这会有所帮助)

Database

//编辑2

要从SharedPreferences中删除任何键/值对,您可以执行以下操作:

SharedPreferences

但是请注意检索值时会发生什么,因为密钥不可用,它将返回默认值,如下所示:

// SharedPreference
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
// Storing
preferences.edit().putString("valueNameOrKey", StringValue).commit();
// Retrieving
preferences.getString("valueNameOrKey", defaultValueToReturnInCaseThatKeyIsNotFound);

因为你可以使用putString,putInt,putBoolean等,get函数也是如此,你的默认值必须与预期的返回类型匹配。