安卓加载本地库

6

我试图使用独立的NDK工具链加载我构建的库。

我已经构建了libGLmove.so,并将其放置在Eclipse项目的libs / armeabi目录中。

然而,调用System.loadLibrary("GLmove")会抛出UnsatisfiedLinkError异常。

有什么想法可以解决这个问题或使Android找到我的库呢? ndk-build在构建后如何打包库呢?

编辑:确切的编译标志为:

/Users/thomas/Documents/android-ndk-r5b/toolchains/arm-eabi-4.4.0/prebuilt/darwin-x86/bin/arm-eabi-g++ --sysroot=/Users/thomas/Documents/android-ndk-r5b/platforms/android-8/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=neon -Wl,--fix-cortex-a8 -fno-exceptions -fno-rtti -nostdlib -fpic -shared -o GLmove.so -O3

5个回答

5
您是否已经检查过生成的 .APK 文件(使用 zip 工具进行查看/解压),以查看您的库是否通过了打包?我有点怀疑可能没有,因为我注意到,在项目和构建机器中构建到“libs”文件夹中的所有内容都进入了 APK 中的一个名为“lib”的文件夹中,而不是“libs”。
如果最终发现 Eclipse 构建过程没有打包任何它不知道的库,那么这并不会让人惊讶。当然,资源的处理方式不同,只要放在正确的位置就会被打包。
如果发现您的库不在 APK 文件中,我认为您不能手动将其放入其中,因为它不会显示在包清单中,并且也会破坏任何签名。
您没有提及您的 Eclipse 项目是否为 NDK 项目(右键单击该项目,选择 Android 工具-> 添加本地支持)如果不是,我认为您需要将其变成一个 NDK 项目,然后将您的库添加到 Android.mk 文件中作为依赖项而不是目标项。
或者:您可以尝试将您的库放入项目中的 /res 目录中,并使用 System.load() 而不是 System.loadLibrary() 进行加载。我承认我自己从未尝试过这样做。

好的,所以在打字之前我应该先试一下。事实证明,如果我将/libs文件夹放入非NDK Eclipse项目中,并将/areabi/libSomething.so放入其中,然后进行普通的Eclipse项目构建,生成的APK确实有/lib/armeabi/libSomething.so,并且它在清单中等等,因此这不太可能是问题所在。另一方面,在您的构建行中使用-march=armv7-a是否意味着架构文件夹应为“/armeabi-v7a”而不是“/armeabi”?当我使用ndk-build时就会得到这个结果。 - jimkberry
1
非常感谢您的回复!我在解压缩APK之后进行了检查,它已被包含在内, 但是在Eclipse中我没有找到Android工具->添加本地支持选项。 这是为什么?我刚刚使用Help->Check for Updates更新了ADT。 - Prime
1
你能在模拟器上安装你的应用程序吗?如果可以,请这样做,然后在Eclipse中进入DDMS视图,选择模拟器设备和“文件浏览器”,并查看:/data/data/your.package.name/lib。你的库在那里吗? - jimkberry
是的,它可以安装在模拟器上,并位于该目录中。它的名称为libglmove.so。我尝试调用System.loadLibrary("glmove");,但出现了相同的错误。 - Prime

2
我遇到了同样的问题。以下是我的错误之处:
  1. 在make文件中,我将"LOCAL_SRC_FILES" 拼写错误。
  2. 在c源代码文件中,我将库名称放在了方法名中。

Java_com_my_namespace_libname_activity_methodName(JNIEnv* env, jobject _this) {
//这里是高级本地代码
}

一旦我修正了这两个问题,重新运行ndk-build,并使用F5刷新了eclipse项目,它就开始工作了。

这个问题特别涉及独立编译器... 如果我错了,请纠正我,但我认为独立编译器不使用Android.mk文件? - Prime
我不知道它是否这样做。我认为,除非定义了不同的制作文件,否则编译器将使用Android.mk文件,但这可能只是我的错误假设。 - zznq

2
您没有提供太多细节,但可能是您构建的.so依赖于在您使用的手机版本上不可用的库。
我还没有找到任何告诉NDK您正在针对哪个Android SDK版本的方法,因此对其应该如何工作没有非常清晰的想法,但看起来很容易从较新的SDK版本中引入一个依赖项到您的.so中,以便它不会在所有手机上加载。

1

抱歉,但是...... 如果您的应用程序需要,该库可以在静态块之外加载。这意味着这不是必需的,而且我仍然会得到相同的异常抛出。 - Prime

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接