Java 通过更改libcore的Runtime.class公开新的艺术功能

Java 通过更改libcore的Runtime.class公开新的艺术功能,java,android,c++,android-source,android-runtime,Java,Android,C++,Android Source,Android Runtime,我已经在Android运行时中插入了一些新功能,现在我想通过一个界面将其公开给外界。由于它是本机代码,我将使用JNI接口调用此新功能,方法与垃圾收集器功能类似:Runtime.getInstance.gc 但是,我不在乎构建一个可以被IDE使用的新SDK,因为我将手动向调用的.dex文件注入字节码 我在libcore/luni中编辑了Runtime.java,在art中编辑了java_lang_Runtime.cc,编辑方式与gc函数类似。我正在生成新的libart.so和core-libart

我已经在Android运行时中插入了一些新功能,现在我想通过一个界面将其公开给外界。由于它是本机代码,我将使用JNI接口调用此新功能,方法与垃圾收集器功能类似:Runtime.getInstance.gc

但是,我不在乎构建一个可以被IDE使用的新SDK,因为我将手动向调用的.dex文件注入字节码

我在libcore/luni中编辑了Runtime.java,在art中编辑了java_lang_Runtime.cc,编辑方式与gc函数类似。我正在生成新的libart.so和core-libart.jar,并在设备上对它们进行闪存。 但是,当我尝试重新启动设备时,会收到以下消息:

Failed to register native method java.lang.Runtime.myMethod()V in /system/framework/core-libart.jar
...
----- class 'Ljava/lang/Runtime;' cl=0x0 -----
vtable (24 entries, 11 in super):
// 24 entries are listed here. My entry is missing.
...
在Runtime.java中,我注册了本机方法,并使用@hide在完整构建中消除了一些警告。例如

/** @hide */
public native void myMethod();
在java_lang_Runtime.cc中,我定义了一个函数,该函数将调用ART internal stuff,并使用宏将其注册到gMethods[]数组。例如

static void Runtime_myMethod(JNIEnv*, jclass) {  
// body
}
原生方法运行时,myMethod,V

设备处于引导循环中。还有其他我应该编辑的文件吗?我应该构建额外的模块,还是在设备上发送任何其他文件

顺便说一句,我不想构建一个新的SDK,因为调用myMethod时,我会将Dalvik字节码注入到APK文件中。基本上,我将获取运行时实例,然后调用该方法。

问题:

Android附带了经过预优化的框架组件。 文件boot.oat包含预先优化的代码或odex代码,可以通过读取boot.art文件中包含的指针来访问这些代码

这两个文件只包含引导类路径的代码。 框架的其余部分以及app和priv app文件夹中的其他系统应用程序都有独立的odex文件

在这个预优化阶段,从框架模块中取出dex代码,使用dex2oat编译jar或apk,生成的代码驻留在我刚才提到的文件中

我尝试过的一些事情:

仅提供libart.so和core-libart.jar是不起作用的,即使后者包含dex代码。这是因为运行时仍在尝试从boot.oat读取该信息

通过修改设备配置进行预优化,aosp构建系统可以生成boot.oat|art和其他odex文件。我原以为所有这些都会起作用,但事实并非如此。 至少对于棉花糖发布分支,在nexus6上

我已经尝试过刷新整个aosp生成的构建,但它不起作用,即使是使用我在禁用verity安全功能的情况下构建的自定义内核

我确信其中一些应该已经起作用了,但是在构建操作系统的过程中必须考虑其他一些东西

解决方案:

最后的办法是去指数化,谢天谢地,它奏效了。 我已经写了一个小的,这样做的Nexus6棉花糖

在第一阶段,脚本从相关位置取出所有oat/odex代码,并将其优化为dex代码,这要归功于和项目。 在第二阶段,它将dex代码打包回框架模块jars/apks中

将一个全新的core-libart.jar发送到设备上仍然不起作用。不知道为什么,但是在将dex文件打包到模块中之前对其进行修补就可以了!:

libart.so现在可以找到Runtime.myMethod,应用程序smali可以再次调用它来运行我在ART中的代码