zoukankan      html  css  js  c++  java
  • DialogFragment异常Fragment already added的原因与解决办法

    DialogFragment异常的表现形式
    快速多次点击按钮展示DialogFragment弹框,100%复现崩溃

    java.lang.IllegalStateException: Fragment already added: XXDialogFragment

    DialogFragment异常的发生原因

    查看DialogFragment的show方法源码,发现每次show的时候都会提交一个add fragment的事务。

    DialogFragment.java

    public void show(FragmentManager manager, String tag) {
        this.mDismissed = false;
        this.mShownByMe = true;
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commit();
    }

    当快速多次点击按钮时,短时间内调用多次show方法,添加多个add事务(add事务A、add事务B等)。然后系统在执行事务队列时,在执行了addFragment后,发现又要add这个Fragment,即抛出异常:

    FragmentManagerImpl.java

    public void addFragment(Fragment fragment, boolean moveToStateNow) {
        if (DEBUG) {
            Log.v("FragmentManager", "add: " + fragment);
        }
    
        this.makeActive(fragment);
        if (!fragment.mDetached) {
            if (this.mAdded.contains(fragment)) {
                throw new IllegalStateException("Fragment already added: " + fragment);
            }
    
            synchronized(this.mAdded) {
                this.mAdded.add(fragment);
            }
    
            fragment.mAdded = true;
            ...
        }
    
    }

    DialogFragment异常的解决办法

    既然知道异常的原因是“执行了多次show方法,添加了多个连续的add事务”。那就改写下show方法,让add事务不连续,每次add之前都把原来的remove掉。解决代码如下:

    public class ActivityDialogFragment extends DialogFragment {
        
        @Override
        public void show(FragmentManager manager, String tag) {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
                if (manager.isDestroyed())
                    return;
            }
            try {
                //在每个add事务前增加一个remove事务,防止连续的add
                manager.beginTransaction().remove(this).commit();
                super.show(manager, tag);
            } catch (Exception e) {
                //同一实例使用不同的tag会异常,这里捕获一下
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    Flex上传文件报“Error #2038”
    AMQ9558
    perl 运算符
    linux gdm 远程桌面访问
    perl 捕获变量
    android apk嵌套 从一个apk启动另外一个apk
    apk调用另一个apk
    ORA-01591 锁被未决分布式事务处理
    jQuery事件控制点击内容下拉
    作业还是作孽?——Leo鉴书79
  • 原文地址:https://www.cnblogs.com/ganzhijie/p/14249580.html
Copyright © 2011-2022 走看看