随着 Android Studio Flamingo 正式版的发布,AGP 8(Android Gradle Plugin 8)也正式进入咱们的视野,这次 AGP 8 相关更新归于「断代式」更新,同时假如想体验 AGP 8,就需求晋级到 Android Studio Flamingo 版别,而晋级到 Flamingo 的话,默许自带的 Java 版别就会变成 JDK 17 所以,这便是你需求适配 AGP8 的首要原因之一。
Flamingo 兼容
首先,如下图所示,运用 Flamingo 不一定就要用 AGP 8,它的支撑范围是 3.2- 8.0
,可是,由于 Flamingo 默许自带的 Java 版别是 JDK 17 ,所以默许情况下你最低需求 AGP 7 。
为什么 Flamingo 默许情况下只能用 AGP 7 ?
如下图1所示,是 Gradle & Java 的版别对照表,能够看到 Gradle 7.3 是第一个支撑 Java 17 的 Gradle 版别,而依据图2 Gradle 和 AGP 的版别对应联系,AGP7.2 开端所需最低 Gradle 版别便是 7.3.3,所以一般情况下主张 Flamingo 运用 AGP 7.2 和 gradle-7.3.3 。
当然,这儿写了所需最低版别,所以你也能够用 AGP 7.0 调配 gradle-7.3 运转,我有的项目便是运用了
build:gradle:7.0.3
/distributions/gradle-7.3-bin.zip
来适配 Flamingo。
别的,你也能够经过修正环境变量和 Android Studio 里的装备来运用低版别的 JDK ,例如经过 Project Structure
– Gradle Settings
– Gradle JDK
来选择外部 JDK 版别,经过下降 JDK 版别来支撑更低的 AGP 版别。
最后,Gradle 版别还和 Kotlin 版别有联系,依据你运用的 Gradle 版别也需求装备对应的 kotlin-gradle-plugin
版别。
所以这儿能够简略先总结一下:
- 要运用 AGP 8 需求 Android Studio Flamingo
- Android Studio Flamingo 自带 JDK17 ,默许情况下最低需求
build:gradle:7.2
/distributions/gradle-7.3.3-bin.zip
,兼容下能够build:gradle:7.0.3
/distributions/gradle-7.3-bin.zip
- 经过装备运用外部 JDK 能够下降 AGP 的版别要求
是不是觉得现在 Android Studio 和 Gradle/Kotlin 联系绑缚得越来越严密?
AGP 8
关于一些人罢了,或许 7 还没用过,8 就又来了,可是 AGP 8 又归于「半断代式」更新,所以仍是有需求适配一下。
AGP Upgrade Assistant
一般情况下我主张运用 AGP Upgrade Assistant 来先主动处理晋级 ,或许还有一些人不知道什么是 AGP Upgrade Assistant ,其实便是你发动 Android Studio 的时分,右下角经常会弹出的提示框,也能够经过 Tools
– AGP Upgrade Assistant
去翻开。
现在的 AGP Upgrade Assistant 已然不是曾经的傻瓜式东西,它已经长大了。
如下图所示,现在的 AGP Upgrade Assistant 已经适当成熟, AS 会依据你当时的 AGP 版别,为你罗列出能够晋级的 AGP 版别进行选择,同时你能够依据需求勾选搬迁的选项,然后 Assistant 会依据你的选择主动调整你当时装备,这关于一些模块较多的项目在搬迁时能够节约许多时刻。
DSL 支撑 namespace
说到 AGP8 适配,首先必提的便是 namespace 的适配需求,晋级到 AGP 8 之后,在 Gradle Sync 的时分你或许会到类似的过错提示 :Namespace not specified
,这是由于 AGP 开端强制要求 namespace 装备。
其实 AGP 7 开端便是有 namespace 装备,而 AGP 8 开端强制要求。
谷歌这次是期望经过 namespace
来让 package
特点得到释放,特别关于 Module 结构来说, namespace
更贴合认知逻辑,而不会像 package
相同还“夹藏”了 applicationId
的特点。
namespace 也和后续的 R id 有关联。
如下图所示是需求调整的逻辑,首要便是移除了 Manifest 文件下的 package
特点 ,然后增加了 build.gradle 文件下的 namespace
装备,这一步推荐运用 AGP Upgrade Assistant 主动搬迁,特别是关于 Module 比较多的项目,能够解放大量重复劳动。
默许参数调整
如下图所示,AGP 8 里一些默许装备参数进行了调整,基本上这部分也是导致项目晋级 AGP 8 跑不起来的「元凶」之一。
当然,假如你是运用 AGP Upgrade Assistant 进行晋级搬迁的话,一般情况下 Assistant 会依据你的项目情况主动进行适配,如下图便是 Assistant 在晋级搬迁时在 gradle,properties
下主动新增的部分。
buildfeatures.buildconfig
假如你需求在 Module 代码里调用 BuildConfig
,那么现在你需求如下代码所示相同装备 buildConfig
:
android {
buildFeatures {
buildConfig = true
}
}
或许直接在 gradle,properties
里全局装备
android.defaults.buildfeatures.buildconfig=true
别的,假如是需求在 Kotlin 里运用 BuildConfig
,还能够装备 BuildConfigAsBytecode
来进步编译速度:
android.enableBuildConfigAsBytecode=true
nonTransitiveRClass
nonTransitiveRClass 也是存在已久的特点,简略来说便是装备非传递性 R 类 ,曾经也有人用它来解决资源冲突,由于 nonTransitiveRClass 会强制要求 Module 的资源按 namespace 来区别运用。
由于这次默许值变成 true,所以假如不想弃用,能够在 gradle,properties
下装备为 false 。
android.nonTransitiveRClass=false
当然,你也能够经过 Android Studio 的主动化搬迁东西来完结,毕竟这部分首要是触及 namespace 声明罢了,官方的主动化脚步处理仍是挺方便的。
处理后也便是从 R 变成了 xxxxxx.xxxx.xxx.R 的作用:
nonFinalResIds
晋级到 AGP8 ,你或许会看到一个过错: Resource IDs will be non-final
,这个问题首要出现在运用 switch
下的 R.id
局面,这个问题假如是没了解过,或许第一眼看到会觉得蒙圈,为什么不能用 R.id
了?
解决问题的最简略方式便是运用装备 nonFinalResIds
为 false ,或许你将 switch
修正为 if
,其实我个人主张仍是直接关闭 nonFinalResIds
来的实际,毕竟一对 if 仍是很难受的。
android.nonFinalResIds=false
enableR8.fullMode
这是一个很有意思的装备,R8 我记住应该是从 Android Studio 3.3 就存在,简略来说,R8 是一站式处理代码紧缩(或 tree-shaking),资源减缩、混杂和优化的进程,一个官方定义比 Proguard 更快且紧缩更好的装备。
默许情况下 AGP 3.4 开端 R8 便是默许编译器,可是它仍是会运用 ProGuard 文件来修正其默许行为,此刻的 R8 是一般形式,也便是之前的 android.enableR8=true
装备,一般形式是兼容 Proguard的,所以用户基本无感。
可是 AGP8 开端 R8 默许是 fullMode
,R8 的 fullMode
会主动处理一些常见的混杂规矩,但它比一般形式优化更激进,例如:
你只经过 Java 反射 API 引用了一个类,
fullMode
下 R8 会觉得你的代码在运转时从不运用这个类,它会直接从 DEX 中删去该类。
当然,假如你的项目里 keep 规矩是完好的,例如反射运用的所有内容都包含在 keep 规矩中,那么 fullMode
应该不会引起什么问题,可是,假如你不期望它工作,那么装备 fullMode
为 false 也是能够的
android.enableR8.fullMode=false
所以适配 fullMode
的首要精力在于针对反射部分的混杂适配,由于假如一不注意,反射部分的 class 在 dex 里就会被 R8 删去。
别的,要输出 R8 在构建项目时使用的所有规矩完好陈述,能够在 proguard-rules.pro
增加:
// You can specify any path and filename.
-printconfiguration ~/tmp/full-r8-config.txt
Plugin 适配
AGP 8 里正式移除了 Transform API 并经过 Artifacts API 和 Instrumentation API 来缩短构建时刻 ,在此之前,咱们一般经过 Transform API 在编译后的 class 文件转换为 dex 文件之前一些自定义打桩处理,而 AGP 8 开端,为了进步构建性能,运用 Transform API 很难与 Gradle 的其它特性结合,所以本次正式移除 Transform API ,这是一些第三方插件需求适配的地方。
别的,在做 Maven 发布的时分,需求增加对应的 singleVariant
来支撑 publications
的兼容,虽然这不是 AGP 8 才开端的,可是也算是需求适配的点之一。
最后
AGP 8 和 Flamingo 需求兼容的问题大致就这样,能够看到 Android Studio 和 Gradle/Kotlin 联系绑缚得越来越严密,假如不了解它们的依靠联系,处理器兼容就会迷失方向。
别的 AGP 现在的每个大版别变动也很大,比方前面没有特别介绍的 aidl
和 renderscript
装备位,下个大版别应该就会被移除了,只能说 Gradle 真的便是为了「折腾」而生。
假如你还有什么问题,欢迎评价交流。