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

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

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


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


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


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

2d74d94d304d915f5e302f59f6bf701.png



看到这里,大概也知道啥原因了,上次就出现过,没总结,这次可不能放过了。关于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();
    }


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


相关文章
|
7月前
|
NoSQL 测试技术 Scala
java.lang.RuntimeException: Can‘t start redis server. Check logs for details.
java.lang.RuntimeException: Can‘t start redis server. Check logs for details.
110 1
|
8月前
|
Java 开发工具 计算机视觉
Caused by: java.lang.UnsatisfiedLinkError: Can‘t load AMD 64-bit .dll on a IA 32-bit platform【已解决】
Caused by: java.lang.UnsatisfiedLinkError: Can‘t load AMD 64-bit .dll on a IA 32-bit platform【已解决】
94 0
|
8月前
|
SQL 关系型数据库 MySQL
java.sql.SQLException: No operations allowed after statement closed.
java.sql.SQLException: No operations allowed after statement closed.
333 0
|
分布式计算 运维 调度
Spark——成功解决java.util.concurrent.TimeoutException: Futures timed out after [600 seconds]
Spark——成功解决java.util.concurrent.TimeoutException: Futures timed out after [600 seconds]
11456 0
|
8月前
|
Oracle 安全 Java
[Java] `JDK17` 模式变量 `Pattern variable` Variable ‘request‘ can be replaced with pattern variable
[Java] `JDK17` 模式变量 `Pattern variable` Variable ‘request‘ can be replaced with pattern variable
112 0
|
8月前
|
XML Java 数据库连接
Type mismatch Can‘t assign java.math.BigDecimal to java.lang.Double
Type mismatch Can‘t assign java.math.BigDecimal to java.lang.Double
104 0
|
Java
【Java异常】com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: can not use this method fo
【Java异常】com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: can not use this method fo
658 0
Can not set final java.lang.Class field org.apache.ibatis.binding.MapperProxy.mapperInterface to com
Can not set final java.lang.Class field org.apache.ibatis.binding.MapperProxy.mapperInterface to com
164 0
|
SQL 人工智能 Java
SQLException: Value ‘0000-00-00 00:00:00‘ can not be represented as java.sql.Timestamp
SQLException: Value ‘0000-00-00 00:00:00‘ can not be represented as java.sql.Timestamp
|
Java 关系型数据库 MySQL
15. 成功解决:java: Can't generate mapping method with primitive return type.
今天启动 SpringBoot 项目时,报了如下错误:`java: Can't generate mapping method with primitive return type.`
1072 0