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

news2024/12/26 21:01:06

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/592441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

揭秘速卖通卖家成功的绝佳秘籍,助您打造畅销店铺!

在竞争激烈的速卖通市场中,如何让您的店铺脱颖而出并实现畅销?林哥今天就跟大家讲一讲一些成功速卖通卖家的绝佳秘籍,帮助您引导高流量和高转化率,成就一个畅销的店铺。 ​一、精确定位目标受众 成功的速卖通店铺离不开精确的目标…

自动生成作文的软件有哪些?盘点五种自动生成作文软件

写作是一项需要花费大量时间和精力的任务,而自动生成作文的软件可以帮助我们节省大量的时间。这些软件通过分析和归纳大量的素材和语言模型,能够快速生成高质量的文章。相比于传统的写作方式,使用自动生成作文软件可以更快地完成文章&#xf…

一套完整的客户管理系统应该包含哪些模块呢?

一套完整的客户管理系统应该包含哪些模块呢? 想要弄清楚一个完整的客户管理系统应该具备哪些功能,首先得清楚系统使用者、使用场景以及主要功能这三个因素。 以我们公司为例: 主要使用者:运营人员、市场人员、产品人员。主要目…

Android Settings中Preference的理解以及使用

Preference 是Android App 中重要的控件之一,Settings 模块大部分都是通过 Preference 实现 优点: Preference 可以自动显示我们上次设置的数据,Android提供preference这个键值对的方式来处理这种情况,自动保存这些数据&#xff…

链接生成二维码怎么弄?这些制作方法分享给大家

在现代社会中,链接生成二维码已经成为了一个非常实用的工具。通过将链接转换为二维码,我们可以将它们轻松地分享给朋友、家人或同事,而无需手动输入URL或复制粘贴。这使得信息的传播变得更加快捷和高效。例如,你正在计划一个聚会&…

Spring第三方bean管理

文章目录 1.第三方bean管理1.1 Bean1.2 小结 2.第三方bean依赖注入2.1 简单类型:成员变量2.2 引用类型:方法形参2.3 小结 3.总结 1.第三方bean管理 1.1 Bean 首先看一下目录结构,APP里面就初始化了SpringConfig文件 SpringConifg中就一句话…

【vue】8个非常实用的Vue自定义指令:

文章目录 一、批量注册指令,新建 directives/index.js 文件二、在 main.js 引入并调用【1】v-copy【2】v-longpress【3】v-debounce【4】v-emoji【5】v-LazyLoad【6】v-permission【7】vue-waterMarker【8】v-draggable 复制粘贴指令 v-copy 长按指令 v-longpress 输…

JUnit单元测试之旅

目录 1. 什么是单元测试和JUnit2. JUnit入门与基本注解2.1测试类的定义:2.2 生命周期注解:2.3断言注解:2.4 参数化单参数多参数通过方法获取参数 2.5 测试套件 三.用到的依赖包 1. 什么是单元测试和JUnit 单元测试(Unit Testing)是对软件中的最小可测试单元进行检查和验证。它…

PyCharm使用指南 - 如何创建密码短语生成器(上)

PyCharm是一种Python IDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外,该IDE提供了一些高级功能,以用于Django框架下的专业Web开发。 PyCharm 最新下载 本文将展示如何使用免费的 PyCharm Community Edition 开…

Java 泛型的介绍

文章目录 1.学习目标2.什么是泛型3.引入泛型语法 4.泛型类的使用语法示例 6.泛型的上界语法示例 7.泛型的方法定义语法示例 8.通配符通配符解决什么问题通配符上界通配符下界 9.包装类基本数据类型和对应的包装类装箱和拆箱自动装箱和自动拆箱 1.学习目标 1.以能阅读 java 集合…

EventLoop事件循环

JavaScript是单线程语言 单线程执行任务队列的问题: 如果前一个任务非常耗时,则后续任务不得不等待,从而导致程序假死的问题。 同步任务和异步任务 ​ 为了防止某个耗时任务程序导致假死的问题,javascript把待执行的任务分为两类: 同步任务(synchronous) 又叫非耗时任务,指…

vue3-实战-02-管理后台项目集成

目录 1-集成element-plus 2-src别名配置 3-环境变量配置 4-svg图标配置 4.1-svg插件安装配置 4.2-svg封装为全局组件 5-集成sass 6-mock数据 7-axios二次封装 上一篇文章记录了项目初始化和项目配置,本章我们来进行项目集成。 1-集成element-plus 本次管…

【PWN · 总结】system返回shell(‘/bin/sh‘、‘sh‘、$(0))

pwn题中要通过system/excute等返回shell,进而cat flag。今天遇到一题,参数$(0)也可返回,有必要记录一下。 目录 前言 一、/bin/sh 1.strings 2.IDA 3.pwntools 4.ROPgadget 5.libc中寻找 二、sh 三、$(0) exp IDA查看机器码 …

交换机的4种网络结构方式:级联方式、堆叠方式、端口聚合方式、分层方式

交换机是计算机网络中重要的网络设备之一,用于实现局域网(LAN)内部的数据转发和通信。交换机可以采用不同的网络结构方式来满足不同的网络需求和拓扑结构。本文将详细介绍交换机的四种网络结构方式:级联方式、堆叠方式、端口聚合方…

c语言编程练习题:7-112 约分最简分式

#include <stdio.h> int gcd(int a,int b) {if(a<b)return gcd(b,a);if(a%b0)return b;elsegcd(b,a%b); } int main(){int a,b;if (scanf("%d/%d",&a,&b)!EOF){// 分析不敲钟的时间int gcd_value gcd(a,b);printf("%d/%d",a/gcd_value,b…

DMBOK知识梳理for CDGA/CDGP——第二章 数据处理伦理

关 注gzh “大数据食铁兽” 回复“知识点”获取《DMBOK知识梳理for CDGA/CDGP》常考知识点&#xff08;第二章数据处理伦理&#xff09; 第二章 数据处理伦理 第二章在 CDGA考试中分值占比不高&#xff0c;CDGP考试不考核。主要侧重点是考概念性的知识&#xff0c;难度较…

Matlab进阶绘图第22期—不等宽柱状图

不等宽柱状图是一种特殊的柱状图。 与常规柱状图相比&#xff0c;不等宽柱状图可以通过柱高与柱宽分别表达两个维度的数据&#xff0c;因此在多个领域得到应用。 在《Matlab论文插图绘制模板第91期》中&#xff0c;虽有介绍过利用Matlab自带bar函数绘制不等宽柱状图的方法&am…

LDGRB-01 3BSE013177R1 将数字输入和继电器输出结合

LDGRB-01 3BSE013177R1包的一部分是全面的通信选项&#xff0c;包括Modbus主/从或CS31&#xff0c;这种产品很少提供。128kB的用户内存和0.1秒/指令的程序处理时间只是AC500-eCo令人印象深刻的性能的两个例子。除了与现有AC500系列的互操作性&#xff0c;AC500-eCo系统还使用基…

PMP-范围管理的重要性

本篇文章主要是方便从事项目管理的“初学者”们了解范围管理的重要性 一、什么是范围管理 项目范围管理包括确保项目做且只做所需的全部工作&#xff0c;以成功完成项目的各个过程。管理项目范围主要在于定义和控制哪些工作应该包括在项目内&#xff0c;哪些不应该包括在项目内…

推动创意成果:创意过程如何改变 2023 年的业务

时下全球经济放缓&#xff0c;很多企业业务都陷入了增长瓶颈&#xff0c;如何突破&#xff1f;今天我们来聊聊一般业务突破的3种方式&#xff1a; 发现一片新的蓝海&#xff0c;迅速杀入占领生态位&#xff08;快&#xff09;&#xff1b; 发现结构性红利机会&#xff0c;大量投…