android - Android下如何交换方法体
问题描述
在纯 Java 中,使用 intrumentation 和 java 代理,有一种方法可以在运行时替换方法体。
不幸java.lang.instrument.Instrumentation
的是,在 Android 下不可用。
我已经检查了所有其他替代方案,例如stackoverflow中描述的替代方案,它指向过时的javassist-android实现。这令人惊讶地有效,但仅适用于新课程。
还有一篇名为Hot swapping code in Android的文章描述了如何在运行时再次加载类,而不是如何替换现有的类方法。
唯一涉及此问题的文章是一篇名为Android hacking: Replace system classes methods with your own的文章,该文章遗漏了源代码并引用了 Dalvik,而不是 ART(因此它不适用于现代硬件)。
那么,有没有办法做到这一点?
...
底线:我想要这样做的原因是在我的应用程序中跟踪特定的方法调用,就像调用此方法时(并在它之前执行一些操作)以及仅当此方法退出时(并对它执行一些操作)。这些方法是在运行时定义的,因此无法在编译时提前知道它们。
解决方案
Android Studio 3.5 中的一项新功能是Apply Changes,它基本上执行与您希望实现的逻辑类似的逻辑:
“.. 我们依靠 Android 8.0 (Oreo) 和更新的设备和模拟器支持的运行时检测来动态重新定义类。”
此外,在亚行播客Esteban de la Canal的第 108 集中提到:
“.. 在 Android Oreo (8.0) 中,平台即时实现了字节码检测,因此我们实际上可以更改正在运行的应用程序的 dexed 类.. 基本上,通过附加 Java 中的 JVMTI等价物,我们可以附加一个经纪人说:你能不能把这个班换成这个班。”
从阅读art/openjdkjvmti源代码开始,即自述文件包含以下内容:
openjdkjvmti 插件
这是 JVMTI v1.2 接口的部分实现,用于 android 运行时作为插件。这允许使用可以通过修改内存中的 dex 文件以及对全局运行时状态执行其他操作来修改程序运行状态的代理。
一旦 Android Studio 3.5 的源代码发布,看看他们如何在Apply Changes实现中使用这些新 API。
推荐阅读
- vue.js - 你如何在 vuex 中正确地调度一个动作?在 Chrome 中获取错误 [vuex] 未知操作类型
- git - 将存储库镜像到另一个存储库中的子文件夹
- node.js - 在 linux nodejs 上获取 USB 打印机的状态
- javascript - 识别 jQuery 中的 HTML 下拉选择
- php - 如何在 PHP 7.4 中分配多维数组?
- reactjs - Material-UI Dialog背景阴影在某些情况下闪烁
- javascript - 我使用了 post 方法仍然出现错误
- c++ - C ++:添加新结构时更新结构指针向量中的所有元素
- php - PHP 脚本将电子邮件文件作为 STDIN 传递到另一个 PHP 解析器,导致间歇性错误
- java - 单个实体 Spring Data JPA 中的“自动生成的 PK 作为 Id”和“自动生成的 UUID 作为字符串”