我看到过一些类似的问题,关于onSaveInstanceState
没有被调用,但是在我的例子中,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());
}
}
}
暂停Activity时(使用后退按钮),onSaveInstanceState
永远不会被调用,因此,在恢复应用时,savedInstanceState
在onCreate
方法中始终为null
。
@Override
public void onPause() {
super.onPause();
onSaveInstanceState(new Bundle());
}
这在https://stackoverflow.com/a/14195202/362657中建议过,但是当onSaveInstanceState
被调用时,savedInstanceState
仍然是onCreate
方法中的null
。
3条答案
按热度按时间polkgigr1#
这里的问题是您误解了
onSaveInstanceState
的工作原理。它被设计为在操作系统由于内存原因或配置更改而需要销毁Activity
/Fragment
的情况下保存它的状态。当Activity
/Fragment
返回/ restarted时,此状态将在onCreate
中传递回来。在
Fragment
中,它们的所有生命周期回调都直接绑定到其父Activity
,因此当其父Activity
调用onSaveInstanceState
时,onSaveInstanceState
在Fragment
上被调用。暂停Activity(使用后退按钮)时,将永远不会调用onSaveInstanceState,因此在恢复应用时,onCreate方法中的savedInstanceState始终为null。
当用户按下返回键时,
Activity
被销毁,因此其子示例Fragment
也被销毁,因此没有理由调用onSaveInstanceState
,因为示例正在被销毁。当您重新打开Activity
时,它是一个全新的示例,没有保存的状态。所以传入onCreate
的Bundle
是null
,这完全符合设计,但是,尝试旋转设备或点击home键,然后您将看到Activity
及其子Fragment
调用了onSaveInstanceState
,并且当返回时在onCreate
中传递回来。你添加的hack,直接在
onPause
内部调用onSaveInstanceState(new Bundle());
,是一个非常糟糕的做法,因为你应该永远不要直接调用生命周期回调。这样做会让你的应用进入非法状态。如果你真正想要的是你的数据在你的应用示例之外持久化,我建议你考虑使用
SharedPreferences
或databases来获得更高级的数据,然后你可以将持久化数据保存在onPause()
中,或者在它发生变化时保存。7fyelxc52#
在对已接受答案的更新中:
如果将
ViewPager
与FragmentStatePagerAdapter
一起使用(而不是FragmentPagerAdapter
),则可以调用片段的onSaveInstanceState
此版本的页导航在页数量较大时更有用,其工作方式更像列表视图。当用户看不到页时,可能会销毁页的整个片段,只保留该片段的保存状态。与FragmentPagerAdapter相比,这使页导航保留的与每个访问的页关联的内存更少,但在页之间切换时,开销可能更大。
别忘了:
使用FragmentPagerAdapter时,主机ViewPager必须设置有效的ID。
deyfvvtc3#
不是这个问题的准确答案,但可能会帮助某人的一天。在我的情况下,我打电话
我将上面的代码替换为下面的代码,一切正常