Apr*_*Ori 8 java-native-interface android dalvik android-ndk
我需要在Android上运行java应用程序的命令行版本(是的,我知道这不是微不足道的).
我正在尝试使用Dalvikvm启动它,它实际上启动但稍后我的代码失败,因为它开始使用android.util.log并抛出此异常.
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)
Run Code Online (Sandbox Code Playgroud)
我尝试设置环境变量,我设置了LD_LIBRARY_PATH和BOOTCLASSPATH变量.我甚至尝试用LD_PRELOAD预加载liblog但没有修复它.似乎dalvikvm设置环境的方式有些不对劲/不同.
Jes*_*eke 13
好问题!我不得不挖掘一下来解决这个问题.
当你使用dalvikvm命令时,libandroid_runtime.so中有一大堆JNI方法在默认情况下不会被绑定.不幸的是,你不能只做一个System.loadLibrary("android_runtime"),因为这实际上并没有绑定所有本机方法.
但是,经过一番挖掘,结果发现有一个内部的,非公共的,不能保证有一个名为com.android.internal.util.WithFramework的类,其目的是加载libandroid_runtime.so并绑定其所有JNI方法.
要使用它,只需com.android.internal.util.WithFramework
在dalvikvm命令上抛出类名,就像这样:
dalvikvm -cp /some/path/classes.dex com.android.internal.util.WithFramework my.example.cls "This is an argument"
Run Code Online (Sandbox Code Playgroud)
(注意:这仅适用于pre-M设备,因为在M中删除了WithFramework类- 感谢@JaredRummler的抬头)
对于android M,我发现此方法有效。
创建一个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 "$@"
Run Code Online (Sandbox Code Playgroud)
app_process似乎在加载所有Java类和共享库的情况下启动了Java代码,因此您可以同时使用其他apk shell命令中使用的SDK类(例如android.util.log.Log和“秘密”本机类,例如ActivityManagerNative),并且在SDK中不存在。
顺便说一句,对于我创建的Java Shell命令,我不得不对上述类使用反射,因为在我看来,
如果不克隆和构建整个AOSP,就无法正确编译...
如果有人知道更简单的方法例如在Java代码中使用ActivityManagerNative而不进行反射,我将感谢您的帮助。
归档时间: |
|
查看次数: |
2793 次 |
最近记录: |