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

随着 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 APIInstrumentation 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 现在的每个大版本变动也很大,比如前面没有特别介绍的 aidlrenderscript 配置位,下个大版本应该就会被移除了,只能说 Gradle 真的就是为了「折腾」而生。

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android Studio Flamingo不是一个官方发布的Android Studio版本,而是一个由社区开发的插件,旨在增强Android Studio的功能。因此,Android Studio 4.2是由Google官方发布的最新版本,而Android Studio Flamingo并不是一个独立的版本,而是一个插件,需要安装在Android Studio中才能使用。因此,Android Studio 4.2是更重要的更新,因为它包含了许多重要的新功能和改进。 ### 回答2: Android Studio Flamingo是一个开发预览版,旨在为开发者提供新功能的早期访问,并收集反馈和改进的机会。相比之下,Android Studio 4.2是一个正式发布的稳定版本,为开发者提供了更可靠和稳定的开发环境。 Flamingo版本的更新频率更高,但存在更多的问题和不稳定性。它通常包含一些实验性的功能和改进,以便开发者可以提前尝试和反馈。这样可以帮助Google收集更多的用户反馈,以改善和优化功能。 而Android Studio 4.2是一个已经发布的正式版本,它经过了更多的测试和稳定性验证。相对来说,它的功能更为成熟和可靠,适合于正式的应用开发和发布。它包含了之前预览版中收集的反馈和改进,为开发者提供了更好的开发环境和工具。 因此,如果你是一个开发者,并希望使用一个稳定和可靠的开发环境,建议选择Android Studio 4.2。如果你对新功能和实验性的改进更感兴趣,并愿意接受一些不稳定性和问题,那么你可以选择Android Studio Flamingo。 ### 回答3: Android Studio Flamingo是一个新的开发预览版,目前还处于早期阶段,而Android Studio 4.2是一个稳定版本的更新。虽然Flamingo版本包含了一些新的功能和改进,但由于其尚未完全稳定和经过广泛测试,因此在实际项目中使用时可能会面临一些不稳定性和兼容性问题。相比之下,Android Studio 4.2是一个经过多次更新和测试的稳定版本,提供了更好的性能和稳定性,更适合日常开发使用。所以,如果你是一个重视稳定性和可靠性的开发者,建议你选择Android Studio 4.2版本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值