DalvikVM上的CLI在JNI lib上失败

我需要在Android上运行Java应用程序的命令行版本(是的,我知道这不是微不足道的)。

我试图启动它使用Dalvikvm,它实际上开始,但以后我的代码失败,因为它开始使用android.util.log并引发此exception。

java.lang.UnsatisfiedLinkError: println_native at android.util.Log.println_native(Native Method) at android.util.Log.i(Log.java:159) at org.slf4j.impl.AndroidLogger.info(AndroidLogger.java:151) at org.gihon.client.TunnelingClient.<init>(TunnelingClient.java:62) at org.gihon.client.CLI.main(CLI.java:95) at dalvik.system.NativeStart.main(Native Method) 

我试着设置环境variables,我设置了LD_LIBRARY_PATH和BOOTCLASSPATHvariables。 我什至尝试用LD_PRELOAD预加载liblog,但没有解决这个问题。 看来,达尔维克姆设定环境的方式是错误的/不同的。

Solutions Collecting From Web of "DalvikVM上的CLI在JNI lib上失败"

好问题! 我不得不挖一点来解决这个问题。

在使用dalvikvm命令时,libandroid_runtime.so中有大量的JNI方法在默认情况下不会被绑定。 不幸的是,你不能只是做一个System.loadLibrary(“android_runtime”),因为这实际上并没有绑定所有的本地方法。

然而,经过一番挖掘,发现有一个内部的,非公开的,不能保证有类com.android.internal.util.WithFramework,其目的是加载libandroid_runtime.so并绑定所有的JNI方法。

要使用它,只需在类名前面的dalvikvm命令中引用com.android.internal.util.WithFramework,如下所示:

 dalvikvm -cp /some/path/classes.dex com.android.internal.util.WithFramework my.example.cls "This is an argument" 

(注意:这仅适用于M之前的设备,因为在M中删除了WithFramework类 – 感谢@JaredRummler)

对于android M,我发现这个方法工作。
创build一个helloworld.sh脚本来陪伴你的jar \ zip文件:

 #!/system/bin/sh # Copied by example from am command base=/system export CLASSPATH=/path/to/your/jar/HelloWorld.jar exec app_process $base/bin HelloWorldMainClass "$@" 

app_process似乎开始与所有Java类和共享库加载的Java代码,所以你可以使用SDK类,如android.util.log.Log和“秘密”的本机类,如ActivityManagerNative,在其他adb shell命令中使用,并不在SDK中。

顺便说一句,对于我创build的java shell命令,我不得不求助于上述类的reflection,因为在我看来,如果不克隆和构build整个AOSP,就无法正确编译…
如果有人知道一个更简单的方法,例如在Java代码中使用ActivityManagerNative而不reflection,我会很感激的帮助。