java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState(已解决)

最近在做提交任务功能,成功提交后点击弹窗返回原来的界面时,程序崩溃了,于是便看了下日志,报错

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 

字面意思:在onSaveInstanceState之后无法执行此操作  

于是慢慢定位到错误的地方,最外层是表示在我的回调函数里dialog的展示有问题,看不出个啥,于是往最里层看,就到了这里

看到这里,大概也知道啥原因了,上次就出现过,没总结,这次可不能放过了。关于DialogFragment其实也是一个fragment,只是其内部绑定了dialog,用于各类弹窗,挺好用的,给个学习链接:https://www.jianshu.com/p/d1852b04a0aa

这里是指在执行onSaveInstanceState之后再调用FragmentTransaction的commit方法导致异常的发生。

原因:commit()方法是在Activity的onSaveInstanceState()之后调用的,使用commit提交的时候会调用到onSaveInstanceState(),而调用onSaveInstanceState()的同时系统就会回收Activity,从而造成整个App的闪退。

解决办法:官方给的解决方法是使用commitAllowingStateLoss方法。

代码实际操作:

利用try catch方法

源代码:我是写了个BaseDialogFragment继承DialogFragment,这样操作性更强一些

   public void show(final String tag) {
        ThreadUtils.runOnUiThread(new Runnable() {
            @SuppressLint("CommitTransaction")
            @Override
            public void run() {
                if (ActivityUtils.isActivityAlive(mActivity)) {
                    FragmentManager fm = mActivity.getSupportFragmentManager();
                    Fragment prev = fm.findFragmentByTag(tag);
                    if (prev != null) {
                        fm.beginTransaction().remove(prev);
                    }
                    BaseDialogFragment.super.show(fm, tag);
                }
            }
        });
    }

更改后:

 public void show(final String tag) {
        ThreadUtils.runOnUiThread(new Runnable() {
            @SuppressLint("CommitTransaction")
            @Override
            public void run() {
                if (ActivityUtils.isActivityAlive(mActivity)) {
                    FragmentManager fm = mActivity.getSupportFragmentManager();
                    Fragment prev = fm.findFragmentByTag(tag);
                    if (prev != null) {
                        fm.beginTransaction().remove(prev);
                    }
                    /*我这儿用的是try-catch
                     *当然也可以直接一刀切,不用commit方法,直接方法一
                     *FragmentTransaction ft = fm.beginTransaction();
                     *ft.add(BaseDialogFragment.this, tag);
                     *ft.commitAllowingStateLoss();
                     */
                    try {
                        BaseDialogFragment.super.show(fm, tag);

                    }catch (IllegalStateException ignore){
                        showAllowingStateLoss(fm,tag);//在这儿调用showAllowingStateLoss
                    }
                }
            }
        });
    }

    public void showAllowingStateLoss(FragmentManager manager, String tag){
        try {
            Field dismissed = DialogFragment.class.getDeclaredField("mDismissed");
            dismissed.setAccessible(true);
            dismissed.set(this, false);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        try {
            Field shown = DialogFragment.class.getDeclaredField("mShownByMe");
            shown.setAccessible(true);
            shown.set(this, true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    } 

这样就解决问题了,当然此方法我个人用着还行,若有不对的地方,望各位大佬指正。

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&岁月不待人&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值