前语

历经几个月的拖延,我总算在今天下午决议将自己的项目从 AGP 7.1.2 & Gradle 7.3.3 搬迁至 AGP 8.0+ & Gradle 8.0+。整体进程还算顺畅,但也遇到了一点问题,结果也比较有意思。本文就记录下搬迁的进程。

开端

基本搬迁

关于提高 AGP 版别,AS 内置了 AGP Upgrade Assistant,能够快速处理一些必要的改变。因而先拿它跑一下。

打开后选择方针版别,上面会明晰地列出将作出的改变。假如你发现 “Run selecyed steps” 按钮为灰色,那么能够检查左边列表中是否有正告项,有的话能够按上面的提示先修正。之后点击按钮,开端跑

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

运转的进程还算顺畅,在下载了一波相关依赖后,咱们的项目总算……同步失利了~ 好吧,这也正常,看看报了啥错

compileDebugJavaWithJavac’ task (current target is 1.8) and ‘kspDebugKotlin’ task (current target is 17) jvm target compatibility

顺带附了个链接:Configure a Gradle project | Kotlin Documentation ,打开一看,嚯,原来是 Java 版别不一样的问题

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

AGP 8.0 要求 JDK 17,这也是 Android Studio F 版别自带的 JDK 版别。

上面写到的解决方法有两种,一是晋级 AGP,二是手动改。作为懒人,先试试第一条路?

尝试再次晋级 AGP

打开 Maven 库房搜一搜(Maven Repository),发现竟然都出到 8.2.0-alpha 了。不敢用不敢用,仍是换个 8.1.0-beta 试试吧

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

更改版别,从头 sync …… 然后,有意思的事情来了,AS F 还不支撑这个 AGP 版别,必须得 G 及以上才行

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

AS 与 AGP 版别对应联系

鉴于我的项目是开源的,要是再要求 AS 必须得是预览版的,这运转要求也太高了。所以仍是换第二条路吧

手动指定

手动设置一下 Java 言语版别和 Kotlin 编译的方针版别

我直接一个大局替换,把两项都指定为 Java 17

compileOption jvmTarget
记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程
记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

至此,应用总算能够正常编译了。到这儿的全部改变能够看 这个 Commit,其中大部分为 AGP Upgrade Assistant 主动完结的。

当然,搬迁到这儿还没有结束,假如检查 gradle.properties 的内容,会发现它为了平滑过渡,其实很多设置仍然保存的与之前相同,这儿或许咱们还能够改善一下

修正 Gradle.properties

先看看 AGP Upgrade Assistant 帮咱们改了哪些内容

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

接下来咱们一条一条看

buildconfig

假如你调用模块代码中的 BuildConfig 类,你需求在你的模块的 build.gradle.kts 文件中,在 android {} 块中启用 buildConfig。不然,BuildConfig 文件不再主动生成。

BuildConfig 文件是一个 Java 文件,包括关于当前构建的静态信息,例如命名空间称号、flavor 称号、调试标志等等。曾经 AGP 总是为全部 Android 模块生成 BuildConfig 文件。假如你开发一个多模块应用程序,你可能会得到许多 AGP 需求处理的 BuildConfig 文件,这会影响你的构建速度。然而,大多数模块不需求从 BuildConfig 类中获取任何信息。

此外,BuildConfig 是一个 Java 文件。假定你的应用程序是用 Kotlin 编写的,在同一模块中混合 Java 和 Kotlin 会进一步影响构建功能。为了缓解这个问题,咱们引入了设置在 gradle.properties 中的 android.enableBuildConfigAsBytecode 标志。当 android.enableBuildConfigAsBytecode=true 时,BuildConfig 文件不再生成为 Java 文件,而是生成为编译文件。这避免了 Java 编译步骤!

我看了下我的代码,的确只有很少的模块用到了 BuildConfig。因而将其值改回 false,并在需求 BuildConfig 的模块中添加:

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

nonFinalResIds

这个首要影响 Java 代码,详细来说,假如设置为 true,那你的 switch-case 里就不能写 id 了,由于它不是 final 的值。如下:

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

但我这个项目是 Kotlin + Jetpack Compose 的,彻底不存在这个问题,因而设为 true 也没问题

nonTransitiveRClass

非传递R类,启用后,主工程不再合并lib库的R文件了,有助于加速编译。假如主工程用了子工程的资源,那引证R的写法都要改变下,需求加上完整的类名

AS 提供了一键搬迁的按钮,点击后能够预览改变,一键处理

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

详细来说,处理后会变成这样:

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

(我才发现引证资源引证错了,怎么跑去运用别人家的库里边的资源了,汗)

至此,上面新增的三项配置项都能够运用默许值了。 到现在,debug 包能够正常运转了。然而,当我尝试 release 包时,它不出意外的报错了……

适配 Release 包

报的什么错呢?如下:

Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in D:\projects\AppProjects\Mine\FunnyTranslation\translate\build\outputs\mapping\release\missing_rules.txt.

打开这个文件看一下,内容如下:

# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.
-dontwarn java.awt.AWTEvent
-dontwarn java.awt.ActiveEvent
-dontwarn java.awt.BorderLayout
-dontwarn java.awt.Color
-dontwarn java.awt.Component
-dontwarn java.awt.Container
-dontwarn java.awt.Dimension
...

按第一行的提示,把里边的内容加入 proguard-rules,从头打包,全部 OK

顺带一提,我封闭了 AGP 8.0 默许的 R8 full 模式,也便是

android.enableR8.fullMode=false

假如开启了 fullMode,则 R8 将愈加急进,详细能够参阅:R8 FAQ

到此的改变能够见 这儿

改变

折腾了一通,最后效果是啥呢?
编译速度方面,按理说应该能提高一定的编译效率,更高地射中缓存。但这个忘掉丈量之前的数据了,就先不谈。

至于体积方面……一顿操作猛如虎,一看体积涨了五??!

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

记一次个人项目迁移到 AGP 8.0+ & Gradle 8.0+ 的全过程

其时我啪的一声站起来了,很快啊,这个 AGP,啊~,不讲武德,来骗,来偷袭,我 20 岁的小同志,这好吗?这不好。我去!我劝,好好反思,不要再耍这样的聪明,小聪明啊……

参阅

  • 5 ways to prepare your app build for Android Studio Flamingo release
  • Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17
  • Flamingo 和 AGP 8 来了,升吗?

本文源代码见:此处