随着 Android Studio Flamingo 正式版的发布,AGP 8(Android Gradle Plugin 8)也正式进入咱们的视野,这次 AGP 8 相关更新归于「断代式」更新,同时假如想体验 AGP 8,就需求晋级到 Android Studio Flamingo 版别,而晋级到 Flamingo 的话,默许自带的 Java 版别就会变成 JDK 17 所以,这便是你需求适配 AGP8 的首要原因之一。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

Flamingo 兼容

首先,如下图所示,运用 Flamingo 不一定就要用 AGP 8,它的支撑范围是 3.2- 8.0 ,可是,由于 Flamingo 默许自带的 Java 版别是 JDK 17 ,所以默许情况下你最低需求 AGP 7

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

为什么 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

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17
Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

当然,这儿写了所需最低版别,所以你也能够用 AGP 7.0 调配 gradle-7.3 运转,我有的项目便是运用了 build:gradle:7.0.3 / distributions/gradle-7.3-bin.zip 来适配 Flamingo。

别的,你也能够经过修正环境变量和 Android Studio 里的装备来运用低版别的 JDK ,例如经过 Project StructureGradle SettingsGradle JDK 来选择外部 JDK 版别,经过下降 JDK 版别来支撑更低的 AGP 版别。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

最后,Gradle 版别还和 Kotlin 版别有联系,依据你运用的 Gradle 版别也需求装备对应的 kotlin-gradle-plugin 版别。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

所以这儿能够简略先总结一下:

  • 要运用 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 的时分,右下角经常会弹出的提示框,也能够经过 ToolsAGP Upgrade Assistant 去翻开。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17
Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

现在的 AGP Upgrade Assistant 已然不是曾经的傻瓜式东西,它已经长大了。

如下图所示,现在的 AGP Upgrade Assistant 已经适当成熟, AS 会依据你当时的 AGP 版别,为你罗列出能够晋级的 AGP 版别进行选择,同时你能够依据需求勾选搬迁的选项,然后 Assistant 会依据你的选择主动调整你当时装备,这关于一些模块较多的项目在搬迁时能够节约许多时刻。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

DSL 支撑 namespace

说到 AGP8 适配,首先必提的便是 namespace 的适配需求,晋级到 AGP 8 之后,在 Gradle Sync 的时分你或许会到类似的过错提示 :Namespace not specified ,这是由于 AGP 开端强制要求 namespace 装备

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

其实 AGP 7 开端便是有 namespace 装备,而 AGP 8 开端强制要求。

谷歌这次是期望经过 namespace 来让 package 特点得到释放,特别关于 Module 结构来说, namespace 更贴合认知逻辑,而不会像 package 相同还“夹藏”了 applicationId 的特点。

namespace 也和后续的 R id 有关联。

如下图所示是需求调整的逻辑,首要便是移除了 Manifest 文件下的 package 特点 ,然后增加了 build.gradle 文件下的 namespace 装备,这一步推荐运用 AGP Upgrade Assistant 主动搬迁,特别是关于 Module 比较多的项目,能够解放大量重复劳动

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

默许参数调整

如下图所示,AGP 8 里一些默许装备参数进行了调整,基本上这部分也是导致项目晋级 AGP 8 跑不起来的「元凶」之一。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

当然,假如你是运用 AGP Upgrade Assistant 进行晋级搬迁的话,一般情况下 Assistant 会依据你的项目情况主动进行适配,如下图便是 Assistant 在晋级搬迁时在 gradle,properties 下主动新增的部分。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

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 声明罢了,官方的主动化脚步处理仍是挺方便的。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

处理后也便是从 R 变成了 xxxxxx.xxxx.xxx.R 的作用:

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

nonFinalResIds

晋级到 AGP8 ,你或许会看到一个过错: Resource IDs will be non-final ,这个问题首要出现在运用 switch 下的 R.id 局面,这个问题假如是没了解过,或许第一眼看到会觉得蒙圈,为什么不能用 R.id 了?

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

解决问题的最简略方式便是运用装备 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 中删去该类。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

当然,假如你的项目里 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 才开端的,可是也算是需求适配的点之一。

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

最后

AGP 8 和 Flamingo 需求兼容的问题大致就这样,能够看到 Android Studio 和 Gradle/Kotlin 联系绑缚得越来越严密,假如不了解它们的依靠联系,处理器兼容就会迷失方向。

别的 AGP 现在的每个大版别变动也很大,比方前面没有特别介绍的 aidlrenderscript 装备位,下个大版别应该就会被移除了,只能说 Gradle 真的便是为了「折腾」而生。

假如你还有什么问题,欢迎评价交流。