在Android 5.0中加载本机库时出现java.lang.UnsatisfiedLinkError

时间:2015-03-27 10:30:05

标签: android android-ndk java-native-interface

我通过以下方式加载我的本地库:

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

以上代码最终打包到Jar文件中。

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

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

请注意,在构建此dexClassLoader实例时,我已指定本机代码所在的路径,即getDir("native", Context.MODE_PRIVATE)

(我使用NDK release 10生成本机库。当生成本机代码文件 libmyNative.so 时,我的java代码(打包到最终的Jar)检查CPU架构键入&将正确的一个复制到getDir("native", Context.MODE_PRIVATE)。)

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

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)

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

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

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

如果你在apk中放置一个“虚拟”32位lib,它与64位设备的需求最匹配,那么系统有望配置你的应用程序以32位兼容模式运行,以便以后加载你真正的32位lib实际上是可行的。

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

可能有一些其他方法可以触发此操作,例如清单中的某些内容(尽管文档中没有提到任何内容)。我不太可能怀疑运行时的任何测量都可以工作,因为在你的任何代码运行之前这个模式可能已经被确定了(看起来你可能最终会在这样的系统上运行两个zygote实例,一个64位,另一个32位,其中的想法是应用程序被认为是合适的推出。