android 未调用SaveInstanceState上的片段活动

9wbgstp7  于 2022-12-25  发布在  Android
关注(0)|答案(3)|浏览(164)

我看到过一些类似的问题,关于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永远不会被调用,因此,在恢复应用时,savedInstanceStateonCreate方法中始终为null

@Override
public void onPause() {
    super.onPause();
    onSaveInstanceState(new Bundle());      
}

这在https://stackoverflow.com/a/14195202/362657中建议过,但是当onSaveInstanceState被调用时,savedInstanceState仍然是onCreate方法中的null

polkgigr

polkgigr1#

这里的问题是您误解了onSaveInstanceState的工作原理。它被设计为在操作系统由于内存原因或配置更改而需要销毁Activity/Fragment的情况下保存它的状态。当Activity/Fragment返回/ restarted时,此状态将在onCreate中传递回来。
Fragment中,它们的所有生命周期回调都直接绑定到其父Activity,因此当其父Activity调用onSaveInstanceState时,onSaveInstanceStateFragment上被调用。
暂停Activity(使用后退按钮)时,将永远不会调用onSaveInstanceState,因此在恢复应用时,onCreate方法中的savedInstanceState始终为null。
当用户按下返回键时,Activity被销毁,因此其子示例Fragment也被销毁,因此没有理由调用onSaveInstanceState,因为示例正在被销毁。当您重新打开Activity时,它是一个全新的示例,没有保存的状态。所以传入onCreateBundlenull,这完全符合设计,但是,尝试旋转设备或点击home键,然后您将看到Activity及其子Fragment调用了onSaveInstanceState,并且当返回时在onCreate中传递回来。
你添加的hack,直接在onPause内部调用onSaveInstanceState(new Bundle());,是一个非常糟糕的做法,因为你应该永远不要直接调用生命周期回调。这样做会让你的应用进入非法状态。
如果你真正想要的是你的数据在你的应用示例之外持久化,我建议你考虑使用SharedPreferencesdatabases来获得更高级的数据,然后你可以将持久化数据保存在onPause()中,或者在它发生变化时保存。

7fyelxc5

7fyelxc52#

在对已接受答案的更新中:
如果将ViewPagerFragmentStatePagerAdapter一起使用(而不是FragmentPagerAdapter),则可以调用片段的onSaveInstanceState

    • 片段状态分页器适配器**

此版本的页导航在页数量较大时更有用,其工作方式更像列表视图。当用户看不到页时,可能会销毁页的整个片段,只保留该片段的保存状态。与FragmentPagerAdapter相比,这使页导航保留的与每个访问的页关联的内存更少,但在页之间切换时,开销可能更大。
别忘了:
使用FragmentPagerAdapter时,主机ViewPager必须设置有效的ID。

deyfvvtc

deyfvvtc3#

不是这个问题的准确答案,但可能会帮助某人的一天。在我的情况下,我打电话

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

我将上面的代码替换为下面的代码,一切正常

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

相关问题