的System.loadLibrary(......)找不到我的情况下,本机库我的、机库、找不到、情况下

2023-09-12 11:07:41 作者:浅笑

我想要使用的另一个 Android项目一个现有的本地库,所以我刚才复制的NDK内置库( libcalculate.so )到我的新的Andr​​oid项目。在我的新的Andr​​oid项目我创建了一个文件夹库/ armeabi / ,把 libcalculate.so 有。有否 JNI /文件夹。我的测试设备具有ARM架构。

在我的Java code我通过加载库:

 静态{
    的System.loadLibrary(计算);
  }
 

当我跑我的新的Andr​​oid项目,我得到了错误:

  java.lang.UnsatisfiedLinkError中:...
nativeLibraryDirectories = [/供应商/ lib中/系统/ lib目录]]]找不到libcalculate.so
 
为什么我在System.Windows.Forms中找不到PaintEventArgs 类

所以,作为错误说,复制的原生库不在/ verdor / lib或/系统/ lib下,如何解决我的情况下,这个问题?

(我解压的APK包,下的lib /有libcalculate.so)

====更新=====

我也试着下创建项目根JNI /文件夹,并在JNI /添加一个Android.mk文件。 Android.mk的含量为:

  LOCAL_PATH:= $(叫我-DIR)

包括$(CLEAR_VARS)
LOCAL_MODULE:= libcalculate
LOCAL_SRC_FILES:= libcalculate.so
包括$(preBUILT_SHARED_LIBRARY)
 

然后,在项目的根,我执行NDK建造。在此之后,armeabi /和armeabi-V7A /由NDK建造产生(与libcalculate.so的文件夹中)的目录。

然后我跑我的Maven的成功构建项目。在最后的APK包,主要有:

 的lib / armeabi / libcalculate.so
LIB / armeabi-V7A / libcalculate.so
 

但是,当我跑我的应用程序,同样的错误抛出:

  java.lang.UnsatisfiedLinkError中:...
nativeLibraryDirectories = [/供应商/ lib中/系统/ lib目录]]]找不到libcalculate.so
 

解决方案

要根本原因(或许可以解决的同时您的问题),这里是你可以做什么:

删除JNI文件夹,所有的的.mk 的文件。你不需要这些,也不是NDK,如果你不编译任何东西。

复制你的 libcalculate.so 文件中<项目> /库/(armeabi | armeabi-V7A | 86 | .. 。)。当采用Android工作室,它的的 jniLibs 的而不是库的,但我看到你使用的Eclipse。

建立你的APK并打开它作为一个的 zip文件的,要检查你的 libcalculate.so 文件里面的 LIB /(armeabi | armeabi-V7A | 86 | ...)

拆卸和安装应用程序

运行的 dumpsys包套餐| grep的yourpackagename 的让你的应用程序的 nativeLibraryPath 或 legacyNativeLibraryDir 的。

运行的 LS 的上的 nativeLibraryPath 的你有,或在 legacyNativeLibraryDir / armeabi 的,要检查你的libcalculate.so确实存在

如果它的存在,检查是否没有被改变从原始的 libcalculate.so 的文件:这是编译的正确的架构,它包含预期的符号,在那里任何缺少的依赖关系。您可以分析libcalculate.so使用readelf。

为了检查步骤5-7,你可以使用我的应用程序,而不是命令行和readelf:的本地利布斯监控

PS:这很容易混淆在哪里.so文件应放置或在默认情况下产生的,这里是一个总结:

库/ CPU_ABI 一个Eclipse项目里面

jniLibs / CPU_ABI 一个Android Studio项目里面

JNI / CPU_ABI 内部的AAR

的lib / CPU_ABI 最后的APK里面

里面的应用程序的 nativeLibraryPath &LT上; 5.0设备和内部应用程序的 legacyNativeLibraryDir / CPU_ARCH 在一个> = 5.0设备

其中 CPU_ABI 是任何的: armeabi,armeabi-V7A,arm64-V8A,86,x86_64的,MIPS,MIPS64 的。根据该架构你的目标和你的库都被编译为。

还要注意的lib未CPU_ABI目录之间的混合:您所需要的全套您使用的是什么,一个lib是在 armeabi 的文件夹不会在安装的 armeabi-V7A 的设备,如果有任何库的APK中的 armeabi-V7A 的文件夹内。

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.

In my java code I load the library by:

  static{
    System.loadLibrary("calculate");
  }

When I run my new android project, I got error:

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"

So, as error says, the copied native library is not in /verdor/lib or /system/lib , how to resolve this problem in my case?

(I unziped the apk package, under lib/ there is libcalculate.so)

====UPDATE=====

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)

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).

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:

Remove the jni folder and all the .mk files. You don't need these nor the NDK if you aren't compiling anything.

Copy your libcalculate.so file inside <project>/libs/(armeabi|armeabi-v7a|x86|...) . When using Android Studio, it's jniLibs instead of libs, but I see you're using eclipse.

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

Run dumpsys package packages | grep yourpackagename to get the nativeLibraryPath or legacyNativeLibraryDir of your application.

Run ls on the nativeLibraryPath you had or on legacyNativeLibraryDir/armeabi, to check if your libcalculate.so is indeed there.

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.

In order to check step 5-7, you can use my application instead of command lines and readelf: Native Libs Monitor

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 inside an eclipse project

jniLibs/CPU_ABI inside an Android Studio project

jni/CPU_ABI inside an AAR

lib/CPU_ABI inside the final APK

inside the app's nativeLibraryPath on a <5.0 device, and inside the app's legacyNativeLibraryDir/CPU_ARCH on a >=5.0 device.

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.

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.