美文网首页
Fragment依赖冲突引起的一个bug及解决

Fragment依赖冲突引起的一个bug及解决

作者: 朔野 | 来源:发表于2017-05-25 15:39 被阅读93次

    这几天碰到一个显示bug,Activity A页面中的一个部分本来是没有数据不应该显示出来的,但是却显示出来了。

    查看代码,发现这个部分是属于fragment B的。如果没有数据,B的根布局会被setVisibilty(gone),但是最终显示效果却是B被显示出来了,这就很诡异了。于是我对B的根布局(一个自定义view)的setVisibilty方法打上断点,发现B被fragmentmanager 调用了getView().setVisibilty(Visible),而B的getView()就是其根布局,终于真相大白了。

    那问题来了,相关代码已经一两年没有动 了,为什么现在出问题了?通过debug,发现debug走的fragment版本是25.1.0,但项目引入的fragment的版本明明是24.2.0。怀疑是和fragment的版本有关,于是调用gradlew:app:dependencies命令,查看项目的依赖,发现最近有个新引入的库,其依赖了support-v4,而且版本是25.1.0。于是尝试exclude support库

      compile("依赖") {
            exclude group: "com.android.support"
        }
    

    再次打包运行,发现问题解决了。看来确实是25.1.0版本的fragment 出了问题。对比下代码,发现确实24.2.0版本和25.1.0版本的framgnet内部实现有了不少变化,v25.1.0多了一个FragmentTransition类,在此类中多次调用fragment.getView().setVisibility()

    所以:

    1. 控制fragment的显示/隐藏,最好还是通过fragmentmanager去操作,不要通过控制fragment的根布局的vibibilty去操作。
    2. 接入新的依赖时注意其引入的间接依赖,避免依赖冲突产生的依赖版本提升

    将support库升级到25.3.1版本后又发现fragmentmanager内部没有再调用fragment.getView().setVisibility()了,所以直接设置fragment根布局的Visibilty也就没有问题了。
    但我觉得,最好还是不要这么做,毕竟support库的framgnet实现经常变,说不定哪天又出问题了。而且fragment毕竟不是view,要控制显示/隐藏,还是通过framgent的方式去做,不能像View那样直接setVisibilty.


    另外,接入第三方lib是不可避免的事,怎么能避免依赖版本冲突带来的影响呢?这里有两种解决版本:

    1. 添加依赖时exclude已有的依赖,如上文的 exclude group: "com.android.support"这样
    2. 在集成打包的module中,指定某个依赖的版本如:
    compile("com.android.support:support-v4:24.2.0") {
            force = true
        }
    

    这样的话,即使其他间接依赖引入了版本高于24.2.0的v4包(如25.1.0),在打包时最终集成进去的也会是24.2.0版本的v4包

    相关文章

      网友评论

          本文标题:Fragment依赖冲突引起的一个bug及解决

          本文链接:https://www.haomeiwen.com/subject/kvczxxtx.html