片段活动onSaveInstanceState未被调用

时间:2013-04-10 20:01:31

标签: android android-fragmentactivity

我已经看到一些关于onSaveInstanceState没有被Fragment调用的类似问题,但在我的情况下Fragment工作正常,它是主要的FragmentActivity麻烦。

相关代码看起来很简单:

public class MyFActivity extends FragmentActivity implements ActionBar.TabListener { 
    String[] allValues; // data to save

    @Override
    protected void onSaveInstanceState (Bundle outState) {
        Log.d("putting it!", allValues.toString());
        outState.putStringArray("allValues", allValues);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            allValues = savedInstanceState.getStringArray("allValues");
            Log.d("getting it!", allValues.toString());
        }
    }
}

暂停活动时(使用后退按钮),永远不会调用onSaveInstanceState,因此,savedInstanceState方法中nullonCreate方法中始终为@Override public void onPause() { super.onPause(); onSaveInstanceState(new Bundle()); } 应用程序。我尝试添加这样的块:

onSaveInstanceState

https://stackoverflow.com/a/14195202/362657中建议但savedInstanceState随后被调用,nullonCreate方法中仍为{{1}}。我错过了什么?

3 个答案:

答案 0 :(得分:78)

这里的问题是你误解了onSaveInstanceState的工作原理。它旨在保存Activity / Fragment的状态,以防操作系统因内存或配置更改而需要销毁它。当onCreate / Activity返回/重新启动时,此状态将在Fragment中传回。

Fragment中,所有生命周期回调都直接与其父Activity绑定。因此onSaveInstanceState在其父Fragment已调用Activity时会调用onSaveInstanceState

  

当暂停活动时(使用后退按钮),永远不会调用onSaveInstanceState,因此,在恢复应用程序时,onCreate方法中的savedInstanceState始终为null。

当按下时,用户正在销毁Activity,因此它的子Fragment已被销毁,因此没有理由调用onSaveInstanceState,因为实例正在被销毁。当您重新打开Activity时,它是一个全新的实例,没有保存状态,因此Bundle中传递的onCreatenull。这与设计完全一致。但是,尝试旋转设备或点击主页按钮,然后您会看到Activity及其子Fragment已调用onSaveInstanceState,并在返回onCreate后返回到。

您添加的 hack ,直接在onSaveInstanceState(new Bundle());内调用onPause,这是一种非常糟糕的做法,因为您应该从不调用生命周期直接回调。这样做会使您的应用程序进入非法状态。

如果你真正想要的是让你的数据在你的应用实例之外存在,我建议你使用SharedPreferencesdatabases来获取更多高级数据。然后,您可以将持久数据保存在onPause()或更改时。

希望这有帮助。

答案 1 :(得分:8)

在接受回答的更新中:

如果您使用onSaveInstanceState ViewPager(而不是FragmentStatePagerAdapter

,则可能会调用片段FragmentPagerAdapter

<强> FragmentStatePagerAdapter

  

当存在大量页面时,此版本的寻呼机更有用,更像列表视图。当页面对用户不可见时,它们的整个片段可能会被破坏,只保留该片段的保存状态。与FragmentPagerAdapter相比,这允许寻呼机保持与每个被访问页面相关联的更少内存,代价是在页面之间切换时可能产生更多开销。

不要忘记:

  

使用FragmentPagerAdapter时,主机ViewPager必须具有有效的ID集。

答案 2 :(得分:0)

不是该问题的准确答案,但可以帮助某人的一天。 就我而言,我打电话给

@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
  super.onSaveInstanceState(outState, outPersistentState);
}

我如下替换了上面的代码,一切正常

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}