美文网首页
Gradle升级4.1(插件3.0.0)变化了哪些东西,需要做哪

Gradle升级4.1(插件3.0.0)变化了哪些东西,需要做哪

作者: 陈文超happylion | 来源:发表于2017-10-27 15:01 被阅读528次

    转载请注明出处:
    Gradle升级4.1(插件3.0.0)变化了哪些东西,需要做哪些改变。
    地址:http://www.jianshu.com/p/8c732dc47edd

    目录

    前言

    gradle升级4.1(插件3.0.0,as 3.0.0)改了不少的东西,尤其是依赖的变化。所以我们还是需要了解一下(升级到3.0以后,编译速度快了不少),对以后添加依赖库/改动build.gradle都是有帮助的。上个测试编译时间对比图:

    提前准备

    升级到gradle插件(gradle-tools)3.0.0:

    • 需要gradle版本升级到4.1以上。
    • android studio版本升级到3.0.0以上。
    • 升级Android SDK Build Tools 版本26.0.0以上

    依赖使用api和implementation,废弃compile

    区别示意图

    提示一下:gradle tools升级到3.0.0以上,compile关键字 已经明确写明废弃了(api关键字的作用等同于之前的compile),但是google官方文档上说“还会保留一段时间,直到下个比较大的gradle tools版本发布”。所以现在仍然使用compile,不会报错。

    gradle插件升级到3.0.0以上最大的区别是依赖方式的改变:

    implementation的“访问隔离”只作用在编译期

    implementation的“访问隔离”只作用在编译期。什么意思呢?如果lib C 依赖了lib A 2.0版本,lib B implementation依赖了lib A 1.0版本:

    • 那么编译期,libC 可访问2.0版本的libA ,libB可访问1.0版本的libA。但最终打到apk中的是2.0版本(通过依赖树可看到)。
    • 在运行期,lib B 和lib C都可访问lib A的2.0版本(因为apk的所有dex都会放到classLoader的dexPathList中)。

    使用implementation有什么好处

    • 如果项目中有很多级联的工程依赖,比如上图中lib A B C的依赖是工程依赖。如果使用的依赖方式是compile/api,那么当lib A接口修改后重新编译时,会重新编译libA B C(即使lib C中并没有用到修改的libA的接口)。如果使用implementation依赖,因为“编译期隔离”的原因,不相关的lib就不会进行重新编译。
    • 如果项目中都是aar依赖,编译减少时长这个优点就没有了(因为aar已经是编译好的字节码了)。那么还有什么用呢?还是以上图为例。之前我们都是compile依赖,如果lib A已经依赖了lib B,那么在libC的build.gradle中就不用写lib A的依赖了。但这样会有问题:
      * 我从lib C的build.gradle的依赖列表中不能完整的知道libC都需要依赖哪些lib。
      * 假设这么一种情况,我知道项目中的依赖的libA的最高版本是2.0,那么app运行时就是使用的这个2.0版本的libA。这时候我需要打一个libC的aar。lib C如果通过compile传递依赖了libA,因此从lib C的build.gradle中不知道lib C 编译时依赖的是哪个版本的lib A。如果libC 打aar(编译)时,依赖的仍然libA 1.0,可能这个aar就有问题了。

    所以使用implementation是一种比较规范的依赖做法。虽然可能需要多写一写依赖,但是项目的可读性是有很大好处的(虽然多写一些依赖,apk打包运行时仍然是采用最高版本的lib,所以对运行不影响)。

    依赖的变种感知(variant-aware dependency)

    什么意思呢?一个项目中需要构建的是某个变种(buildType+flavors 如SpeedDebug),那么当构建依赖的lib时,会自动寻找对应的变种(SpeedDebug)进行构建。所以这就有个问题,有可能你依赖的lib里面并没有对应的变种,怎么办吧?新版本的gradle中提供了一些api来解决这种事情,比如:

    android {
         buildTypes {
         debug {}
         release {}
         staging {
            // Specifies a sorted list of fallback build types that the
            // plugin should try to use when a dependency does not include a
            // "staging" build type. You may specify as many fallbacks as you
            // like, and the plugin selects the first build type that's
            // available in the dependency.
            matchingFallbacks = ['debug', 'qa', 'release']
        }
    }
    }
    

    具体可以看官方指南。不过因为我们的依赖一般都是aar依赖,并且lib中也一般不会写一些特别的buildType或flavor,所以这个对我们没啥影响。
    这里需要注意一个规范:
    对于渠道类型(flavor),必须添加 flavor dimension,就算你所有的渠道只有一种维度。(好在亮总已经添加过了,所以没我什么事了~~),使用方式就是在productFlavors块前面添加flavorDimensions:

     // Specifies two flavor dimensions.
     flavorDimensions "tier", "minApi"
    
     productFlavors {
     free {
      // Assigns this product flavor to the "tier" flavor dimension. Specifying
      // this property is optional if you are using only one dimension.
      dimension "tier"
      ...
    }
    
    paid {
      dimension "tier"
      ...
    }
    
    minApi23 {
        dimension "minApi"
        ...
    }
    
    minApi18 {
        dimension "minApi"
        ...
    }
    }
    

    因为build时有了变种感知功能,所以我们在工程依赖的时候就不需要写类似(写了会报错):

      debugImplementation project(path: ':library', configuration: 'debug')
    

    这种的依赖方式的了。当我们build一个debug变种时,对于工程依赖直接写如下所示就可以了:

       implementation project(':library')
    

    对于aar依赖,我们仍然可以使用指定变种类型的依赖,如:

       debugImplementation 'com.example.android:app-magic:12.3'
    

    围绕变种感知功能,还牵扯一些其他的一些改变,需要的可以看用户指南

    一些坑

    • 找不到apkVariantData:

       Could not get unknown property 'apkVariantData' for object of type com.android.build.gradle.internal.api.ApplicationVariantImpl.   
      

    什么原因呢?gradle插件3.0.0版本 升级了gradle的api,导致有些api不能用。恰好AndResGuard 1.2.3版本插件用到了这个过期的api。所以升级没办法了。那AndResGuard有没有新的版本呢?



    抱歉,暂时还没有。所以先注释掉。到时候再改吧~

    • 需要显示声明annotation Processor库

         Error:Execution failed for task ':aimovie:javaPreCompileDebug'.Annotation processors must be explicitly declared now.  The following dependencies on the compile classpath are found to contain annotation processor.  Please add them to the annotationProcessor configuration.- roboblender-3.0.1.jar (org.roboguice:roboblender:3.0.1)Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior.  Note that this option is deprecated and will be removed in the future.See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.
      

    什么原因导致的这个错误呢?在gradle插件3.0.0之前的版本中,如果你写了compile a ,那么不但会把lib a 放到compile classpath 路径下,还会自动放到processor classpath路径下。这会导致processor classpath路径下有大量不必要的依赖,这会更加编译时间。所以从gradle插件3.0.0以后,如果一个库是annotation processors库(如果库中还有META-INF/services/javax.annotation.processing.Processor,那么就认为这是一个annotation processors库),那么需要自己手动使用annotationProcessor关键字添加:

         dependencies {
              ...
         annotationProcessor 'com.google.dagger:dagger-compiler:<version-number>'
         }
    

    并且,如果发现annotation processors库也存在于compile classpath路径下,那么就会报错。所以这么说的话,我们就不能使用compile/api/implementation来依赖一个annotation processors库了,只能使用annotationProcessor关键字来依赖annotation processors库。但如果annotation processors库也需要放到compile classpath 路径下,怎么办呢?那么需要使用compile/api/implementation再声明依赖一次。注意新版本中,compile/api/implementation这些关键字只会把这个库放到compile classpath路径下,不再放到processor classpath路径下。所以,如果一个annotation processors库要放到processor classpath和compile classpath两个路径下,那么需要用两个关键字声明两次。那么前面说了,如果发现annotation processors库在processor classpath路径会报错,所以需要在android defaultConfig块中进行声明不进行错误检查。

          android {
             ...
            defaultConfig {
            ...
              javaCompileOptions {
                 annotationProcessorOptions {
                   includeCompileClasspath false
               }
             }
          }
         }
    

    当然,如果不想那么麻烦,直接使用如下配置也可以,但是这样的配置在之后的gradle插件版本中并不支持,所以不推荐。

         android {
             ...
            defaultConfig {
            ...
              javaCompileOptions {
                 annotationProcessorOptions {
                   includeCompileClasspath true
               }
             }
          }
         }

    相关文章

      网友评论

          本文标题:Gradle升级4.1(插件3.0.0)变化了哪些东西,需要做哪

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