onSaveInstanceState问题分析

产生的现象

我们在测试app的时候,有时候会碰到这样的问题”java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState”,具体的状况如下图所示
这里写图片描述
一般出现在我们往activity容器里面添加Fragment,或者是Fragment之间进行切换的时候比较容易出现这样的问题。

问题的原因及复现

首先我们看如何复现这个问题,如以下代码所示,创建activity,5秒钟之后,往activity里面添加Fragment。在这5秒之内按下home键,然后等待handler代码执行,接着就可以看到log里面报出“onSaveInstanceState”的错误了。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Fragment fragment = new TestFragment();
                showFragment(fragment,"first");
            }
        },5000);


    }

    private void showFragment(Fragment fragment,String tag){
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.container, fragment, tag);
        ft.addToBackStack(null);
        ft.commit();
    }

为什么会出现这个问题呢,我们可以通过log稍微的追踪以下源码。打开log里面爆出这个错误的链接,可以发现,爆出这个异常的是checkStateLoss()函数,当mStateSaved为true时,就会抛出这个异常。
这里写图片描述
这里写图片描述
继续追踪就会发现,当activity执行onSaveInstance()的时候,就会将mStateSaved置为true。所以对于刚才的场景,当我们按下home键,activity会自动的执行到onSaveInstance,此时再执行commit函数,就会爆出这样的异常了。有时候当我们快速进行切换,或者跑一些自动测试脚本的时候,就有可能会出现这个问题。

解决问题

其实这个问题挺好解决的,只需要将commit换成commitAllowingStateLoss就可以了
这里写图片描述
官方给出的解释如下

commitAllowingStateLoss
added in API level 11

public abstract int commitAllowingStateLoss ()

Like commit() but allows the commit to be executed after an activity's state is saved.
This is dangerous because the commit can be lost 
if the activity needs to later be restored from its state,
so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user. 

commitAllowingStateLoss与commit差不多,但有可能会导致状态的丢失。不过目前我还没有遇到过状态丢失的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值