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

转载请注明出处:
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
           }
         }
      }
     }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容