Apply Changes 在 Android 11 中的增强特性
source link: https://mp.weixin.qq.com/s?__biz=MzAwODY4OTk2Mg%3D%3D&%3Bmid=2652076873&%3Bidx=1&%3Bsn=660d47dd5c6dd8a872d08d26293d3654
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
简介
Apply Changes 是 Android Studio 中的一项功能,我们在 Android Studio 3.5 中引入了这项功能 ,以帮助开发者快速迭代您对应用所做的更改。Apply Changes 通过 JVMTI API 来判断是否可以使用此方式进行变更。在 Android 11 上,ART (Android 运行时) 扩展了 JVMTI API,引入了一个名为 Structural Class Redefinition (类的结构性重定义) 的新功能。该功能使 Apply Changes 在 Android 11 设备上增加了一类新的应用场景。现在,可以使用 Apply Changes 将更复杂的修改快速部署到正在运行的应用上,这包括:
-
增加方法 (Android Studio 4.1)
-
增加资源文件 (Android Studio 4.2)
-
增加静态字段 (Android Studio 4.2)
这可以使您减少研发周期,最大化生产效率。本文我们将探讨在 Android Studio 中该功能是如何实现的。
-
Android Studio 3.5 中引入了这项功能
https://medium.com/androiddevelopers/android-studio-project-marble-apply-changes-e3048662e8cd
-
JVMTI API
https://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html
通过 Android Studio 实现更强的功能
Apply Changes 基于 Android Runtime 特性从头设计,所以可以利用其升级更新的功能不断发展。
对于类的结构性重定义而言,将具有新增方法的类发送到 ART,这与之前的 Android 版本没有什么不同。如今新增了一个入口 API,为此您需要将 Android Studio 升级到 4.1 或更高版本,以利用动态在运行中添加新方法的优势,包括静态方法和虚方法。
但是,增加变量需要在 Android Studio 中进行新的分析。当增加一个新的变量时,ART 不会尝试为其分配具体的值。(请持续关注后续关于 ART 实现类的结构性重定义的文章)。取而代之的是,被增加的变量仅会被初始化为默认初始值或 null,并且如何初始化将由 Android Studio 决定。
此过程较为复杂,考虑这样一种情况: 将 long 类型静态变量 y 添加到类中 (y 的初始化发生在类加载期间)。例如:
public class example {
public final static long x = System.currentTimeMillis();
public final static long y = System.currentTimeMillis();
}
如果该类被加载,x 和 y 的值将会非常接近。在通过使用 Apply Code Changes 增加 y 的情况下,很难计算出正确的 y 值。事实上对 y 的赋值,即使采用最接近的模拟类加载和初始化 y 的程序,也是有争议的。因为两个 curentTimeMillis() 在静态初始化 ( <clinit> 方法) 中调用,Apply Changes 将继续遵守不重新执行 <clinit> 方法任何部分的策略,所以新增的 y 值为 0。
幸运的是,Apply Changes 已经 使用了 D8 分析 DEX 文件 ,并且作为该过程的一部分,在最新版本的 Android Studio 中,Apply Changes 能够利用 D8 新引入的 Inspector API。这种轻量级的检查 API 能够在 DEX 比较过程中计算出一些额外的信息,而仅需增加少量开销 (仅检查发生修改的 Java 类)。一系列有关新增变量的元信息将被附加在发送到对应设备的 Apply Changes 请求的 ProtoBuf 消息中。
-
Inspector
https://r8.googlesource.com/r8/+/refs/heads/master/src/main/java/com/android/tools/r8/inspector/
在设备上,Android Studio 将我们的更改传达给 VM 之前,Java Agent 将检查即将被替换的当前加载类。通过比较当前加载类和新编译类的字段,即可计算出新增字段列表及每个字段的初始值。然后,代理程序将暂时挂起所有其他线程,防止未初始化的新增字段在替换前被访问。如果替换请求成功执行,它将使用合适的变量初始化新增字段。
局限与即将推出的新功能
在 Android Studio 4.2 Canary 3 中,此功能仅支持新增静态原语的应用场景。作为衍生功能,这有助于在 R.class 中新增值,使 Apply Changes 支持新增资源。
对于所有使用 Apply Changes 的场景中,需要记住一点: 当您重新编译并重新运行一个程序,任何语义和之前都是不同的。试想这样的一个例子: 构造函数发生了变化,但是所有基于原来的构造函数初始化的对象并没有重新初始化。同样的,该规则也适用于静态变量,因为 <clinits> 不会被重新调用。
希望 Android Studio 中这一新功能可以为开发者带来生产力的提高。我们一如既往地欢迎大家给我们 反馈 ,并让我们知道您希望看到哪些改 进。
-
反馈
https://issuetracker.google.com/issues/new?component=192708
一本手册尽览 Android 11 最新特性与开发技巧
更有成功心得助您举一反三
☟ 即刻下载 ☟
推荐阅读
点击屏末 | 阅 读 原 文 | 即刻访问 Android 官方中文文档
Recommend
-
3
利用任务调度特性检测Android模拟器 leonnewton
-
12
利用cache特性检测Android模拟器 leonnewton
-
44
本文主要阐述了Lambda表达式及其底层实现(invokedynamic指令)的原理、Android第三方插件RetroLambda对其的支持过程、Android官方最新的dex编译器D8对其的编译支持。通过对这三个方面的跟踪分析,以Java 8的代表性特性——Lambda表达式为着...
-
50
Java 8 概述 Java 8 是 Java 开发语言非常重要的一个版本。Oracle 从 2014 年 3 月 18 日发布 Java 8,从该版本起,Java 开始支持函数式编程。特别是吸收了运行在 JVM 上的 Scala、Groovy 等动态脚本语言的特性之后,Java 8 在...
-
13
Joost van Schaik Senior Mixed Real...
-
7
Android 增强版百分比布局库 为了适配而扩展 ...
-
5
Google披露Android 5.0的三大安全特性 – Android开发中文站你的位置:Android开发中文站 > 热点资讯 > Google披露Android 5.0的三大安全特性
-
1
Android 13 来了,但我更愿意叫它 Android 12 增强版 Google Pixel 6 系列上的 bug 还没修复完,新版本的 Android 13 就正式对外公布,像极了小学考试时,匆忙交卷而没注意反面还有一道 40 分的大题。
-
5
系统版本适配是每个应用都需要面对的问题,很多同学表示很难跟上系统的更新步伐,对版本适配也是抱着能拖就拖的态度。相比于功能缺陷,兼容问题往往更加隐蔽,有些问题往轻了说只是用户体验稍微差些。测试没发现,产品不提,老板不懂,得过且过皆大欢喜,早点下班不...
-
2
Apply configuration changes to the default node pool in AKS via Bicep In today’s blog post we look into the Bicep and how to apply configuration changes to the default node pool in Azure Kuber...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK