我已经看到一些关于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
方法中null
在onCreate
方法中始终为@Override
public void onPause() {
super.onPause();
onSaveInstanceState(new Bundle());
}
应用程序。我尝试添加这样的块:
onSaveInstanceState
在https://stackoverflow.com/a/14195202/362657中建议但savedInstanceState
随后被调用,null
在onCreate
方法中仍为{{1}}。我错过了什么?
答案 0 :(得分:78)
这里的问题是你误解了onSaveInstanceState
的工作原理。它旨在保存Activity
/ Fragment
的状态,以防操作系统因内存或配置更改而需要销毁它。当onCreate
/ Activity
返回/重新启动时,此状态将在Fragment
中传回。
在Fragment
中,所有生命周期回调都直接与其父Activity
绑定。因此onSaveInstanceState
在其父Fragment
已调用Activity
时会调用onSaveInstanceState
。
当暂停活动时(使用后退按钮),永远不会调用onSaveInstanceState,因此,在恢复应用程序时,onCreate方法中的savedInstanceState始终为null。
当按下时,用户正在销毁Activity
,因此它的子Fragment
已被销毁,因此没有理由调用onSaveInstanceState
,因为实例正在被销毁。当您重新打开Activity
时,它是一个全新的实例,没有保存状态,因此Bundle
中传递的onCreate
为null
。这与设计完全一致。但是,尝试旋转设备或点击主页按钮,然后您会看到Activity
及其子Fragment
已调用onSaveInstanceState
,并在返回onCreate
后返回到。
您添加的 hack ,直接在onSaveInstanceState(new Bundle());
内调用onPause
,这是一种非常糟糕的做法,因为您应该从不调用生命周期直接回调。这样做会使您的应用程序进入非法状态。
如果你真正想要的是让你的数据在你的应用实例之外存在,我建议你使用SharedPreferences
或databases来获取更多高级数据。然后,您可以将持久数据保存在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);
}