System.loadLibrary(...) 在我的情况下找不到本机库 [英] System.loadLibrary(...) couldn't find native library in my case
问题描述
我想使用来自另一个 Android 项目的现有本机库,因此我只是将 NDK 构建的库 (libcalculate.so) 复制到我的新 Android 项目中.在我的新 Android 项目中,我创建了一个文件夹 libs/armeabi/
并将 libcalculate.so 放在那里.没有 jni/文件夹.我的测试设备采用 ARM 架构.
I want to use a existing native library from another Android project, so I just copied the NDK built library (libcalculate.so) to my new Android project. In my new Android project I created a folder libs/armeabi/
and put libcalculate.so there. There is no jni/ folder. My testing device has ARM architecture.
在我的 java 代码中,我通过以下方式加载库:
In my java code I load the library by:
static{
System.loadLibrary("calculate");
}
当我运行我的新 android 项目时,出现错误:
When I run my new android project, I got error:
java.lang.UnsatisfiedLinkError: ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"
因此,正如错误所说,复制的本机库不在/verdor/lib 或/system/lib 中,在我的情况下如何解决此问题?
So, as error says, the copied native library is not in /verdor/lib or /system/lib , how to resolve this problem in my case?
(我解压了apk包,lib/下有libcalculate.so)
(I unziped the apk package, under lib/ there is libcalculate.so)
====更新======
我也尝试在项目根目录下创建一个jni/文件夹,在jni/下添加一个Android.mk文件.Android.mk 的内容是:
I also tried to create a jni/ folder under project root, and add an Android.mk file under jni/. The content of Android.mk is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)
然后,在项目根目录下,我执行了 ndk-build .然后通过ndk-build生成armeabi/和armeabi-v7a/目录(文件夹内有libcalculate.so)
Then, under project root, I executed ndk-build . After that, the armeabi/ and armeabi-v7a/ directories are generated by ndk-build (with libcalculate.so inside the folder).
然后我运行我的maven构建项目成功.在最终的 apk 包中,有:
Then I run my maven build the project successfully. In the final apk package, there are:
lib/armeabi/libcalculate.so
lib/armeabi-v7a/libcalculate.so
但是当我运行我的应用程序时,抛出同样的错误:
But when I run my app, the same error throw:
java.lang.UnsatisfiedLinkError: ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"
推荐答案
为了根本原因(也许同时解决您的问题),您可以这样做:
To root cause (and maybe solve your issue in the same time), here is what you can do:
删除 jni 文件夹和所有 .mk 文件.如果您不编译任何内容,则不需要这些或 NDK.
Remove the jni folder and all the .mk files. You don't need these nor the NDK if you aren't compiling anything.
将您的 libcalculate.so
文件复制到
中.使用 Android Studio 时,它是
,但我看到您正在使用 eclipse.
Copy your libcalculate.so
file inside <project>/libs/(armeabi|armeabi-v7a|x86|...)
. When using Android Studio, it's <project>/app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...)
, but I see you're using eclipse.
构建您的 APK 并将其作为 zip 文件打开,以检查您的 libcalculate.so
文件是否在 lib/(armeabi|armeabi-v7a|x86|...).
Build your APK and open it as a zip file, to check that your libcalculate.so
file is inside lib/(armeabi|armeabi-v7a|x86|...).
删除并安装您的应用程序
Remove and install your application
运行dumpsys 包包|grep yourpackagename 以获取应用程序的 nativeLibraryPath 或 legacyNativeLibraryDir.
Run dumpsys package packages | grep yourpackagename to get the nativeLibraryPath or legacyNativeLibraryDir of your application.
在您拥有的 nativeLibraryPath 或 legacyNativeLibraryDir/armeabi 上运行 ls,以检查您的 libcalculate.so 是否确实存在.
Run ls on the nativeLibraryPath you had or on legacyNativeLibraryDir/armeabi, to check if your libcalculate.so is indeed there.
如果它在那里,请检查它是否没有从您的原始 libcalculate.so 文件中更改:它是否针对正确的体系结构编译,是否包含预期的符号,是否存在任何缺少的依赖项.您可以使用 readelf 分析 libcalculate.so.
If it's there, check if it hasn't been altered from your original libcalculate.so file: is it compiled against the right architecture, does it contain the expected symbols, are there any missing dependencies. You can analyze libcalculate.so using readelf.
为了检查第 5-7 步,您可以使用我的应用程序代替命令行和 readelf:本机库监视器
In order to check step 5-7, you can use my application instead of command lines and readelf: Native Libs Monitor
PS:很容易混淆默认情况下应该放置或生成 .so 文件的位置,这里是一个摘要:
PS: It's easy to get confused on where .so files should be put or generated by default, here is a summary:
libs/CPU_ABI 在 Eclipse 项目中
libs/CPU_ABI inside an eclipse project
jniLibs/CPU_ABI 在 Android Studio 项目中
jniLibs/CPU_ABI inside an Android Studio project
jni/CPU_ABI 在 AAR 中
lib/CPU_ABI 在最终 APK 中
在 <5.0 设备上应用的 nativeLibraryPath 内部,以及在 >=5.0 设备上应用的 legacyNativeLibraryDir/CPU_ARCH 内部.
inside the app's nativeLibraryPath on a <5.0 device, and inside the app's legacyNativeLibraryDir/CPU_ARCH on a >=5.0 device.
其中 CPU_ABI 是以下任一项:armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips、mips64.取决于您的目标架构和您的库已经编译.
Where CPU_ABI is any of: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64. Depending on which architectures you're targeting and your libs have been compiled for.
另请注意,CPU_ABI 目录之间不会混合库:您需要使用的完整集合,armeabi 文件夹内的库不会安装在 armeabi-v7a 设备,如果 APK 中的 armeabi-v7a 文件夹中有任何库.
Note also that libs aren't mixed between CPU_ABI directories: you need the full set of what you're using, a lib that is inside the armeabi folder will not be installed on a armeabi-v7a device if there are any libs inside the armeabi-v7a folder from the APK.
这篇关于System.loadLibrary(...) 在我的情况下找不到本机库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!