本文介绍了DalvikVM 上的 CLI 在 JNI 库上失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 Android 上运行命令行版本的 java 应用程序(是的,我知道这并不简单).

I need to run a command line version of java application on Android(Yeah I know it's not trivial).

我正在尝试使用 Dalvikvm 启动它,它实际上启动了,但后来我的代码失败了,因为它开始使用 android.util.log 并抛出此异常.

I'm trying to start it using Dalvikvm, it actually starts but somewhere later my code fails because it starts using android.util.log and throws this 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)

我尝试设置环境变量,设置了 LD_LIBRARY_PATH 和 BOOTCLASSPATH 变量.我什至尝试使用 LD_PRELOAD 预加载 liblog,但没有解决这个问题.dalvikvm 设置环境的方式似乎有问题/不同.

I tried setting the environment variables, I set the LD_LIBRARY_PATH and the BOOTCLASSPATH variables. I even tried preloading liblog with LD_PRELOAD but nothing fixed that.It seems that something is wrong/different with the way dalvikvm sets the environment.

推荐答案

好问题!我不得不挖掘一下才能弄清楚这一点.

Good question! I had to dig a bit to figure this out.

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

There are a slew of JNI methods in libandroid_runtime.so that don't get bound by default, when you're using the dalvikvm command. Unfortunately, you can't just do a System.loadLibrary("android_runtime"), because this doesn't actually bind all the native methods.

然而,经过一番挖掘,事实证明有一个内部的、非公开的、不保证存在的类,名为 com.android.internal.util.WithFramework,其目的是加载 libandroid_runtime.so 并绑定其所有JNI 方法.

However, after some digging, it turns out there is an internal, non-public, not guaranteed to be there class called com.android.internal.util.WithFramework, whose purpose is to load libandroid_runtime.so and bind all its JNI methods.

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

To use it, just throw com.android.internal.util.WithFramework in front of your class name, on the dalvikvm command, like so:

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

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

(Note: This only works on pre-M devices, due to the WithFramework class being removed in M - thanks for the heads up @JaredRummler)

这篇关于DalvikVM 上的 CLI 在 JNI 库上失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-18 04:45