在 Android 5.0 中加载本机库时出现 java.lang.UnsatisfiedLinkError [英] java.lang.UnsatisfiedLinkError when loading native library in Android 5.0

查看:19
本文介绍了在 Android 5.0 中加载本机库时出现 java.lang.UnsatisfiedLinkError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过以下方式加载我的原生库:

I am loading my native library by:

try {
       System.loadLibrary("myNative");
} catch (UnsatisfiedLinkError e) {
       //java.lang.UnsatisfiedLinkError here
       System.load("/data/data/com.my.app/app_native/libmyNative.so");
}

以上代码最终打包成一个Jar文件.

The above code is finally packaged to a Jar file.

在另一个项目中,我使用 DexClassLoader 加载上述 Jar:

In another project, I load the above Jar with DexClassLoader:

DexClassLoader dexClassLoader = new DexClassLoader(jarPath,
                    optJarPath,
                    getDir("native", Context.MODE_PRIVATE),
                    getClassLoader());

注意,在构造这个dexClassLoader实例的时候,我已经指定了native代码所在的path,即getDir("native", Context.MODE_PRIVATE).

Notice that when constructing this dexClassLoader instance, I have specified the path where the native code is located, that's getDir("native", Context.MODE_PRIVATE).

(我正在使用 NDK release 10 生成原生库. 当生成原生代码文件 libmyNative.so 时,我的 java 代码(打包到最终 Jar)检查 CPU 架构类型并将正确的复制到 getDir("native",Context.MODE_PRIVATE).)

(I am using NDK release 10 to generate the native library. When the native code file libmyNative.so is generated, my java code (which packaged to final Jar) checks the CPU architecture type & copy the right one to getDir("native", Context.MODE_PRIVATE).)

上述代码在除 Android 5.0 Lollipop 之外的其他设备上运行良好.在 Android 5.0 Lollipop 设备上运行时,我不断收到以下错误:

The above code works fine on other devices except Android 5.0 Lollipop. When run on Android 5.0 Lollipop device, I constantly get the following error:

java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/com.my.app/app_native/libmyNative.so" is 32-bit instead of 64-bit
at java.lang.Runtime.load(Runtime.java:331)
at java.lang.System.load(System.java:982)

如何解决这个问题?

推荐答案

您似乎试图在 64 位目标上使用 32 位库.如果您不能提供 64 位,则必须说服 Android 回退到 32 位模式以适应该库.

You appear to be attempting to use a 32-bit library on a 64-bit target. If you can't provide a 64-bit one, you will have to convince Android to fallback to 32-bit mode to accommodate the library.

显然,兼容性模式(来源似乎将其称为 ABI 覆盖)通常在安装时设置,安装程序发现只有 32 位(而不是 64 位)库可用.但是在您的情况下,该库在安装时不可见,因此不起作用.

Apparently, compatibility mode (the source seems to call it an ABI override) is normally set at install time, by the installer discovering that only 32-bit (and not 64-bit) libraries are available. But in your case, the library is not visible at install time, so that won't work.

如果您在最符合 64 位设备需求的 apk 中放置一个虚拟"32 位库,那么系统有望将您的应用配置为在 32 位兼容模式下运行,以便稍后加载你真正的 32 位库实际上可以工作.

If you place a "dummy" 32-bit lib in the apk that is the closest match for the 64-bit device's needs, then the system will hopefully configure your app to run in 32-bit compatibility mode so that later loading your real 32-bit lib will actually work.

我不知道 32 位库是否需要是真正的库而不是具有正确位置和合理名称的空文件,但是 ndk 示例文件夹的 libhello-jni.so 中的 hello-jni 项目应该工作.您不需要任何相应的 java 代码,只需要有一个安装程序可以发现的本机库(但是,作为测试调用它可能不是一个坏主意).

I don't know if the 32-bit lib would need to be a real one vs. an empty file with the correct location and plausible name, but the hello-jni project from the ndk samples folder's libhello-jni.so should should work. You won't need any corresponding java code, just to have a native library the installer can discover (however, calling into it as a test might not be a bad idea).

可能有一些其他方式来触发它,例如清单中的某些内容(尽管文档中没有提到任何内容).我不太可能怀疑运行时的任何措施都会起作用,因为这种模式可能在您的任何代码运行之前已经牢固设置(看起来您实际上可能最终会在这样的系统上运行两个 zygote 实例,一个是 64 位,另一个是 32 位,其想法是应用程序由被认为合适的任何一个启动).

It is possible there may be some other way(s) to trigger this, such as something in the manifest (though nothing is mentioned in the documentation). I'd be less likely to suspect that any measures at runtime will work, since this mode may already be firmly set before any of your code runs (it looks like you may actually end up with two instances of zygote running on such a system, one 64 bit and the other 32, with the idea being that apps get launched by whichever one is believed to be appropriate).

这篇关于在 Android 5.0 中加载本机库时出现 java.lang.UnsatisfiedLinkError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆