关于使用butterknife出现的fragment重复添加的问题

Posted 疯狂小芋头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于使用butterknife出现的fragment重复添加的问题相关的知识,希望对你有一定的参考价值。

1. 关于使用butterknife出现的fragment重复添加的问题

出现此问题时,实际上仅从错误信息是无法看出是由于butterknife引起的。但是由于前后修改的内容中最重要的就是butterknife所以只能是由于他引起的。

这个地方就以下出现的异常信息进行说明并记录,注意使用的场景可能需要相同才会出现此问题。

12-17 12:08:09.988 11459-11459/cn.xxxx.xxx E/CrashReport: java.lang.IllegalStateException: Fragment already added: HomeFragment14c82c9 (ca93c917-7e5b-44da-94a3-f14c9d437125) id=0x7f09043a android:switcher:2131297338:0
        at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
        at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5490)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-17 12:08:09.988 11459-11459/cn.xxxx.xxx E/CrashReport: #++++++++++++++++++++++++++++++++++++++++++#
12-17 12:08:10.195 11459-11459/cn.xxxx.xxx E/CrashReport: sys default last handle start!
12-17 12:08:10.196 11459-11459/cn.xxxx.xxx E/CrashReport: sys default last handle end!
12-17 12:08:10.202 11459-11494/cn.xxxx.xxx E/EveriskLog-Loader-UncaughtExceptionAction: start write UncaughtException to everisk_jcrash.txt
12-17 12:08:10.203 11459-11494/? E/EveriskLog-Loader-UncaughtExceptionAction: java.lang.IllegalStateException: Fragment already added: HomeFragment14c82c9 (ca93c917-7e5b-44da-94a3-f14c9d437125) id=0x7f09043a android:switcher:2131297338:0
        at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
        at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
    	at 
12-17 12:08:10.204 11459-11494/? E/EveriskLog-Loader-UncaughtExceptionAction: android.app.ActivityThread.main(ActivityThread.java:5490)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-17 12:08:10.204 11459-11494/? E/EveriskLog-Loader-UncaughtExceptionAction: start write UncaughtException to everisk_jcrash.txt
12-17 12:08:10.204 11459-11494/? E/EveriskLog-Loader-UncaughtExceptionAction: java.lang.IllegalStateException: Fragment already added: HomeFragment14c82c9 (ca93c917-7e5b-44da-94a3-f14c9d437125) id=0x7f09043a android:switcher:2131297338:0
        at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
        at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
    	at 
12-17 12:08:10.204 11459-11494/? E/EveriskLog-Loader-UncaughtExceptionAction: android.app.ActivityThread.main(ActivityThread.java:5490)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    
    
    --------- beginning of crash
12-17 12:08:10.205 11459-11494/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: cn.xxxx.xxx, PID: 11459
    java.lang.IllegalStateException: Fragment already added: HomeFragment14c82c9 (ca93c917-7e5b-44da-94a3-f14c9d437125) id=0x7f09043a android:switcher:2131297338:0
        at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
        at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5490)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

1.1. 使用场景

在使用HomeFragment显示首页时,由于控件会通过butterKnife的@BindView绑定显示,这个是很常见的操作,但是在实际业务中,存在相同的页面业务逻辑完全一样(调用接口或处理逻辑都一样),仅仅区别只是UI不一样的情况。

这里的UI是指整个页面的UI如风格、配色、按钮位置、样式等。在这种情况下选择了将UI显示抽象出接口,通过接口提供业务数据,由具体的UI表现去展示和处理数据(通过加载不同的xml及处理)。

UI抽象接口的通过IDisplay类似的接口去实现,并在实现类中使用butterknife绑定了相应页面的控件。最终是通过同一个fragment页面调用IDisplay的接口进行UI展示的。

1.2. 问题原因

在不同的UI抽象接口实现类中,在初始时使用的UI控件的名称是一致的(从旧xml中创建并修改了样式,ID未进行修改),该问题就是直接导致了以上的异常。

猜测原因是butterknife绑定时相同的ID会被与绑定的页面关联,导致了加载时由于使用了相同的ID,该页面可能会通过不同的IDisplay进行加载,所以出现重复添加fragment的情况。

大概的问题情况与原因如上。解决方案是很明确的:使用不同的xml页面时,强烈建议使用不同的页面ID,至少将可能用于同一页面的xml中的控件命名一致

1.3. 其它注意事项

解决此问题的还有一个注意事项,在解决时务必卸载掉原APP后再重新安装调试。在实际操作中出现过已经解决掉了重复ID的问题,依然会不断地报以上错误,该问题在clean project的情况下也不会消失。猜测是原已安装的APP可能存在一定的数据缓存或未更新导致了问题重复出现

尽管从理论上来说并没有开启Instant Run/Hotsopt时,应用重新运行时应该重新安装的,不会出现以上情况,但是确实发生过。特此以作记录。

以上是关于关于使用butterknife出现的fragment重复添加的问题的主要内容,如果未能解决你的问题,请参考以下文章

关于Android Studio升级4.1版本后ButterKnife插件不兼容的问题

关于ButterKnife 8.1.0使用遇到的问题

butterknife使用出现问题

butterknife的使用和一个常见错误的解决

Android Studio上方便使用butterknife注解框架的偷懒插件Android Butterknife Z

butterknife的8.5.1版本问题