AGP9.0的主要变更项,给Gradle来一次大变样

AGP9.0出来有一段时间了,但一直没有真正去了解它更新了些啥,跟以前有啥不一样,毕竟升级了一个大版本,那么借今天这篇文章,就一起来看下AGP9.0

版本兼容性对比

首先要知道一点,如果想要让AGP升级到9.0,那么你的一些其他组件必须满足以下要求

  • Gradle:最低版本必须为9.1.0
  • SDK build tools:最低为36.0.0
  • NDK:对应版本为28.2.13676358
  • 最高支持的API Level:不能超过36.1

DSL类只实现新的公共接口

这个是AGP9.0一个大的变化,在以前的AGP版本中比如7.x或者8.x,既包含着新的接口,也同样包含着旧的DSL类型BaseExtension,这种做法就像是服务端的接口,每次新增功能的同时,老的接口依然保留,为的就是兼容线上老版本,这个AGP也是一样的道理,导致的结果是,我们依然一直在使用旧的DSL类型,至于新的接口,很少有人在用,所以在9.0版本上做了一次类似于强制更新一样的操作,要求所有开发者,只要更新到了9.0,那么就必须使用新的接口,同时旧的Variant API访问也会改变,替代方案如下

废弃 API (8.x) 替换方案 (9.0)
applicationVariantslibraryVariantstestVariantsunitTestVariants androidComponents.onVariants
variantFilter androidComponents.beforeVariants
deviceProvidertestServer Gradle Managed Devices
sdkDirectoryndkDirectorybootClasspath 等路径访问 androidComponents.sdkComponents
dexOptions 无直接替换(dx 已被 d8 取代)
generatePureSplits Android App Bundle 内置分发

迁移要求

当你决定将你的项目的AGP迁移至9.0的时候,那么一定要注意以下几点

  1. 确保项目与内置 Kotlin 兼容(不再使用 org.jetbrains.kotlin.android
  2. KMP 项目需切换到 com.android.kotlin.multiplatform.library 插件
  3. 所有自定义构建逻辑中的内部 DSL 引用必须替换为公共 DSL 接口
  4. 第三方插件必须升级到 AGP 9.0 兼容版本

退出机制

当然谷歌但凡有了一次重大更新,那么势必也会提供一个开关让你平滑过渡,为的是比如一些三方库因使用旧版本的AGP而导致兼容性的问题,方式很简单,在gradle.properties里面将newDsl开关置成false即可

当然这种好事将会在AGP10.0里面取消,将会彻底移除退出机制,据说这个版本将会在2026年中推出,在此之前,在AGP9.4版本中,也允许按模块退出,方式就是在gradle.properties里面加上如下配置

内置 Kotlin 支持

另一个重大更新是9.0里面默认内置了kotlin支持并且是处于启用状态,这个就意味着我们以后没有必要在gradle文件里面手动管理KGP版本,AGP9.0会自动帮你依赖上KGP2.2.10版本,但是如果你的项目的KGP版本比2.2.10要高,那么还是得手动去升级一下内置的KGP或者KSP版本

那么有升级肯定还会有降级,如果项目的KGP版本要求比内置版本要低,我们只能去降级,不过降级之前还必须做一件事情,就是关闭内置kotlin功能,不然开着的话依然还是使用默认的内置版本2.2.10,关闭的方式也很简单,在gradle.properties中加入如下配置即可

降级的方式与升级略有些不同,需要使用严格版本

不过这个降级也是有底线的,最低只能降低到2.0.0版本

默认值变化

以下是 AGP 8.13 到 9.0 默认值翻转的属性,这样可以在升级的时候,评估保留哪些旧版本上的行为

Gradle 属性 8.13 默认值 9.0 默认值 影响
android.newDsl false true 新 DSL 默认启用
android.builtInKotlin false true 内置 Kotlin 默认启用
android.uniquePackageNames false true 所有库必须使用唯一包名
android.useAndroidx false true 强制使用 AndroidX
android.default.androidx.test.runner false true 默认使用 AndroidJUnitRunner
android.dependency.useConstraints true false 影响依赖导入优化
android.enableAppCompileTimeRClass false true R class 常量需要重构(switch → if 链)
android.sdk.defaultTargetSdkToCompileSdkIfUnset false true 未设置 targetSdk 时默认等于 compileSdk
android.onlyEnableUnitTestForTheTestedBuildType false true 仅对测试的构建类型启用单元测试
android.proguard.failOnMissingFiles false true ProGuard 文件缺失将报错
android.r8.optimizedResourceShrinking false true 资源压缩默认优化
android.r8.strictFullModeForKeepRules false true Keep 规则更严格(需显式保留构造器)
android.defaults.buildfeatures.resvalues true false 仅在需要 resValues 的子项目中启用
android.defaults.buildfeatures.shaders true false 仅在需要着色器的子项目中启用
android.r8.proguardAndroidTxt.disallowed false true 只支持 proguard-android-optimize.txt
android.r8.globalOptionsInConsumerRules.disallowed false true 库发布时禁止保留文件中含全局选项
android.sourceset.disallowProvider false true 必须使用 Sources API 注册生成的源码
android.custom.shader.path.required false true 必须配置 glslc.dir

已移除的功能

功能 8.x 状态 9.0
Wear OS 嵌入式应用支持 可用 移除wearApp 配置被删除)
androidDependencies 任务 可用 移除
sourceSets 报告任务 可用 移除
Density Split APK 支持 可用 移除(改用 App Bundle)

已移除的DSL项

  • AndroidSourceSet.jni(功能从未正常工作)
  • AndroidSourceSet.wearAppConfigurationName
  • BuildType.isRenderscriptDebuggable(功能从未正常工作)
  • DependencyVariantSelection → 替换为 DependencySelection,后者以 kotlin.android.localDependencySelection 的形式公开
  • Installation.installOptions(String),它已被 Installation.installOptions 的可变属性取代
  • 实验性但从未稳定过的 PostProcessing
  • ProductFlavor.setDimension → 替换为 dimension 属性
  • LanguageSplitOptions,仅对已弃用的Google Play免安装体验有用
  • DensitySplit,因为该功能不再受支持。 替代方案是使用 App Bundle

已移除的 API

8.x API 9.0 替换
AndroidComponentsExtension.finalizeDSl finalizeDsl(大小写修正)
Component.transformClassesWith Instrumentation.transformClassesWith
Component.setAsmFramesComputationMode Instrumentation.setAsmFramesComputationMode
ComponentBuilder.enabled ComponentBuilder.enable
DependenciesInfoBuilder.includedInApk includedInApk
DependenciesInfoBuilder.includedInBundle includedInBundle
GeneratesApk.targetSdkVersion targetSdk
Variant.minSdkVersion / maxSdkVersion / targetSdkVersion minSdk / maxSdk / targetSdk
VariantBuilder.targetSdk或targetSdkPreview GeneratesApkBuilder.targetSdk或GeneratesApkBuilder.targetSdkPreview
VariantOutput.enable enabled
移除了VariantBuilder.unitTestEnabled 取而代之的是在扩展HasUnitTestBuilderVariantBuilder子类型上名称更一致的enableUnitTest
FeaturePluginFeatureExtension 已废弃并停止
BaseExtension.registerTransform 已废弃并停用

已移除的 Gradle 属性

  • android.defaults.buildfeatures.aidl :改为各子项目单独配置 buildFeatures { aidl = true }
  • android.defaults.buildfeatures.renderscript :改为各子项目单独配置

强制执行的Gradle属性

  • android.r8.integratedResourceShrinking : 强制执行,使用即报错
  • android.enableNewResourceShrinker.preciseShrinking : 强制执行

DSL 变化:CommonExtension 形参化移除

这是源码级破坏性变更,旨在帮助避免未来出现源代码级重大变更,但这也意味着,块方法需要从 CommonExtension 移至 ApplicationExtensionLibraryExtensionDynamicFeatureExtensionTestExtension

AGP 8.13

AGP 9.0

R8 变化

新选项:-processkotlinnullchecks

配置 R8 如何处理 Kotlin 空值检查:

参数值 行为
keep 不做任何更改
remove_message(默认) 重写为调用 getClass(),保留空值检查但移除消息
remove 完全移除空值检查

Keep规则不再传播到 Companion 方法

  • 之前:匹配接口方法的 keep 规则会自动传播到合成的同伴方法上
  • 9.0:不再传播,影响 minSdk < 24 时的接口反糖化

默认 SourceFile 变更

SourceFile 改为 r8-map-id-<MAP_ID>,支持 Logcat 自动堆栈回溯。

合成类名最小化

L8 反脱糖生成的 DEX 中的 j$ 类使用短名称格式(如 $1),不再包含 $$ExternalSynthetic 长编码名。

移除项

  • -addconfigurationdebugging 支持移除(使用会出编译警告)
  • D8Command.builder.setDesugaredLibraryKeepRuleConsumer 移除
  • R8Command.Builder.setDesugaredLibraryKeepRuleConsumer 移除

最后

不愧是大版本的更新,已经跟之前的版本有了很明显的变化,个人感觉对于大部分项目,要做这个版本的升级还是需要好好规划一下,这可能是有史以来最折腾的一次升级,不过换个角度来想,跨过这道坎以后,项目的构建脚本将会变得更加简洁,可维护,所以长痛不如短痛,趁早把这件事做了吧

相关推荐
数聚天成DeepSData1 小时前
外贸海关进出口数据去哪免费下载?从统计到明细的查找指南
linux·服务器·开发语言·前端·网络·人工智能·自然语言处理
半夜里咳嗽的狼1 小时前
组件进侧栏就变形?用 CSS Container Queries 把响应式边界收回组件
前端·css
xx24061 小时前
前端性能优化笔记
前端·笔记·性能优化
带娃的IT创业者2 小时前
单文件架构的极致美学:深入解析 Bento 的 HTML 幻灯片技术实现
前端·架构·html·web开发·bento·单文件架构
muddjsv2 小时前
CSS 值的完整计算过程:指定值、计算值、使用值、实际值与动态依赖
前端·css
恋猫de小郭2 小时前
KotlinLLM 开源 ,一个可以在运行时自己生成永久 Kotlin 代码的 Agent 库
android·前端·人工智能
名字还没想好☜2 小时前
React createPortal 实战:模态框逃出 overflow:hidden、事件冒泡与焦点管理
前端·javascript·react.js·ecmascript·react·createportal
游戏开发爱好者82 小时前
iOS应用加固方案全解析:源码加固与IPA在线加固对比
android·macos·ios·小程序·uni-app·cocoa·iphone
用户059540174462 小时前
Playwright测试AI记忆存储踩坑实录:这个时序问题让我排查了6小时
前端·css