惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
H
Help Net Security
Jina AI
Jina AI
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
博客园 - 叶小钗
Y
Y Combinator Blog
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
WordPress大学
WordPress大学
C
Check Point Blog
Recent Announcements
Recent Announcements
IT之家
IT之家
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Azure Blog
Microsoft Azure Blog
V
Visual Studio Blog
B
Blog

博客园 - ganzhijie

清除应用缓存 Glide将网络图片压缩成指定大小并保存到本地 Android加固之后Apk重签名 Mac显示和隐藏“隐藏文件”命令 Android Installation failed with message INSTALL_FAILED_TEST_ONLY Could not find any version that matches com.android.support:appcompat-v7:30.+.的解决步骤 ndk{abiFilters:}的使用 Android Studio解决support-annotations版本冲突 解决javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.的问题 如何查看手机cpu是32位还是64位 Android DialogFragment 遇到 java.lang.IllegalStateException: Fragment already added: 的解决方法 查看apk安装包的AndroidManifest.xml文件 ListView中动态显示和隐藏Header&Footer Android动画效果translate、scale、alpha、rotate Android手机主流屏幕分辨率有哪些? OPhone中的图片特效处理 Android手势(上,下,左和右的判断) Android UI秘笈:谨记该做什么不该做什么 Android permission 访问权限大全
DialogFragment异常Fragment already added的原因与解决办法
ganzhijie · 2021-01-08 · via 博客园 - ganzhijie

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();
        }
    }
}