Android System.loadLibrary(…)无法';在我的案例中找不到本机库

Android System.loadLibrary(…)无法';在我的案例中找不到本机库,android,android-ndk,Android,Android Ndk,我想使用另一个Android项目中的现有本机库,所以我刚刚将NDK构建库(libcalculate.so)复制到我的新Android项目中。在我的新Android项目中,我创建了一个文件夹libs/armeabi/,并将libcalculate.so放在那里。没有jni/文件夹。我的测试设备具有ARM架构 在java代码中,我通过以下方式加载库: static{ System.loadLibrary("calculate"); } 当我运行新的android项目时,我遇到了错误

我想使用另一个Android项目中的现有本机库,所以我刚刚将NDK构建库(libcalculate.so)复制到我的新Android项目中。在我的新Android项目中,我创建了一个文件夹
libs/armeabi/
,并将libcalculate.so放在那里。没有jni/文件夹。我的测试设备具有ARM架构

在java代码中,我通过以下方式加载库:

  static{
    System.loadLibrary("calculate");
  }
当我运行新的android项目时,我遇到了错误:

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"
所以,正如错误所说,复制的本机库不在/verdor/lib或/system/lib中,在我的例子中如何解决这个问题

(我解压了apk包,在lib/there is libcalculate.so下)

===更新====

我还尝试在projectroot下创建一个jni/文件夹,并在jni/下添加一个Android.mk文件。Android.mk的内容是:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)
然后,在projectroot下,我执行ndk构建。然后,通过ndk build生成armeabi/和armeabi-v7a/目录(其中libcalculate.so位于文件夹中)

然后我运行我的maven,成功地构建项目。在最终的apk包中,有:

lib/armeabi/libcalculate.so
lib/armeabi-v7a/libcalculate.so
但当我运行我的应用程序时,同样的错误会抛出:

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

实际上,您不能将.so文件放在
/libs/armeabi/
中,然后使用
System.loadLibrary
加载它。您需要创建一个Android.mk文件,并声明一个预构建模块,在其中指定.so文件作为源

为此,请将.so文件和Android.mk文件放在
jni
文件夹中。 您的Android.mk应该是这样的:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

来源:

实际上,您不能将.so文件放入
/libs/armeabi/
并使用
System.loadLibrary
加载它。您需要创建一个Android.mk文件,并声明一个预构建模块,在其中指定.so文件作为源

为此,请将.so文件和Android.mk文件放在
jni
文件夹中。 您的Android.mk应该是这样的:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

来源:

尝试在包含
预构建的共享\u库
部分后呼叫您的库:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := <PATH>/libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

#...

LOCAL_SHARED_LIBRARIES += libcalculate
LOCAL\u路径:=$(调用我的目录)
包括$(清除变量)
本地_模块:=libcalculate
本地_SRC_文件:=/libcalculate.so
包括$(预建共享库)
#...
本地共享库+=libcalculate
更新:

如果要在Java中使用此库,则需要将其编译为共享库

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := <PATH>/libcalculate.so
include $(BUILD_SHARED_LIBRARY)
LOCAL\u路径:=$(调用我的目录)
包括$(清除变量)
本地_模块:=libcalculate
本地_SRC_文件:=/libcalculate.so
包括$(构建共享库)

您需要在
/vendor/lib
目录中部署库。

尝试在包含
预构建共享库
部分后调用您的库:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := <PATH>/libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

#...

LOCAL_SHARED_LIBRARIES += libcalculate
LOCAL\u路径:=$(调用我的目录)
包括$(清除变量)
本地_模块:=libcalculate
本地_SRC_文件:=/libcalculate.so
包括$(预建共享库)
#...
本地共享库+=libcalculate
更新:

如果要在Java中使用此库,则需要将其编译为共享库

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := <PATH>/libcalculate.so
include $(BUILD_SHARED_LIBRARY)
LOCAL\u路径:=$(调用我的目录)
包括$(清除变量)
本地_模块:=libcalculate
本地_SRC_文件:=/libcalculate.so
包括$(构建共享库)

您需要在
/vendor/lib
目录中部署库。

您使用的是gradle吗?如果是这样,将
.so
文件放入
/src/main/jniLibs/armeabi/


我希望这会有帮助。

你在用gradle吗?如果是这样,将
.so
文件放入
/src/main/jniLibs/armeabi/

我希望它能有所帮助。

要想找到根本原因(同时解决您的问题),您可以做以下几点:

  • 删除jni文件夹和所有.mk文件。如果不编译任何内容,则不需要这些或NDK

  • 将您的
    libcalculate.so
    文件复制到
    /libs/(armeabi | armeabi-v7a | x86 |…)
    中。当使用Android Studio时,它是
    /app/src/main/jniLibs/(armeabi | armeabi-v7a | x86 |…)
    ,但我看到您使用的是eclipse

  • 构建APK并将其作为zip文件打开,以检查
    libcalculate.so
    文件是否位于lib/(armeabi | armeabi-v7a | x86 |…)中

  • 删除并安装应用程序

  • 运行dumpsys package packages | grep yourpackename以获取应用程序的nativeLibraryPath或legacyNativeLibraryDir

  • 在您拥有的nativeLibraryPath或legacyNativeLibraryDir/armeabi上运行ls,检查libcalculate.so是否确实存在

  • 如果存在,请检查它是否与原始libcalculate.so文件不同:它是否根据正确的体系结构编译,是否包含预期的符号,是否缺少依赖项。您可以使用readelf分析libcalculate.so

  • 为了检查步骤5-7,您可以使用我的应用程序而不是命令行和readelf:

    PS:很容易混淆文件的位置。因此默认情况下,文件应该放置或生成,下面是一个摘要:

    • eclipse项目内部的libs/CPU\u ABI

    • jniLibs/CPU\u ABI安卓工作室项目内部

    • AAR内部的jni/CPU\u ABI

    • 最终APK中的lib/CPU\u ABI

    • 在应用程序的nativeLibraryPath中找到根本原因(可能同时解决您的问题),以下是您可以做的:

    • 删除jni文件夹和所有.mk文件。如果不编译任何内容,则不需要这些或NDK

    • 将您的
      libcalculate.so
      文件复制到
      /libs/(armeabi | armeabi-v7a | x86 |…)
      中。当使用Android Studio时,它是
      /app/src/main/jniLibs/(armeabi | armeabi-v7a | x86 |…)
      ,但我看到您使用的是eclipse

    • 构建APK并将其作为zip文件打开,以便
      ndk {
              moduleName "serial_port"
              ldLibs "log", "z", "m"
              abiFilters "arm64-v8a","armeabi", "armeabi-v7a", "x86","x86_64","mips","mips64"
      }
      
      APP_ABI := arm64-v8a armeabi armeabi-v7a x86 x86_64 mips mips64
      
      /data/data/<PackageName>/lib
      /data/app-lib/<PackageName>-1/lib
      /data/app-lib/<PackageName>-2/lib
      /data/app/<PackageName>-1/lib
      /data/app/<PackageName>-2/lib
      
      // Return Full path to the directory where native JNI libraries are stored.
      private static String getNativeLibraryDir(Context context) {
          ApplicationInfo appInfo = context.getApplicationInfo();
          return appInfo.nativeLibraryDir;
      }
      
      android {
          defaultConfig {
              ...
              ndk {
                  abiFilters 'armeabi-v7a'
              }
         }
      }
      
      defaultConfig {
          ...
      
          ndk {
              abiFilters 'armeabi-v7a'
          }
          ...
      }
      
      android.useDeprecatedNdk=true
      
      defaultConfig {
      ndk {
                  abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
          }
      }