I have inserted some new functionality in the Android Runtime (ART), and now I want to expose it to the outside world via an interface. As it is native code, I will be using the JNI
interface to call this new functionality, in a similar way with the Garbage Collector functionality: Runtime.getInstance().gc()
.
However, I don't care in building a new SDK that could be used by an IDE, as I will be manually injecting bytecode to .dex files that will make the call.
I have edited the Runtime.java
in libcore/luni
, and java_lang_Runtime.cc
in art
in a similar way with the gc()
function. I am generating the new libart.so
and core-libart.jar
and I flash them on a device.
However, when I try to reboot the device, I get the message:
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.
...
In the Runtime.java
I register the native method and supress some warnings on a full build using @hide. eg,
/** @hide */
public native void myMethod();
In the java_lang_Runtime.cc
, I define the function (that will call the ART internal stuff) and register it to the gMethods[] array using a macro. eg,
static void Runtime_myMethod(JNIEnv*, jclass) {
// body
}
NATIVE_METHOD(Runtime, myMethod, "()V")
The device is on a bootloop. Are there any other files that I should have edited? Should I build extra modules, or send any other files on the device?
BTW, I do NOT want to build a new SDK
as for calling myMethod
I will inject Dalvik bytecode
to an APK file. Basically I will get the Runtime instance, and then call the method.