【问题标题】:Android NDK java.lang.UnsatisfiedLinkError: findLibrary returned nullAndroid NDK java.lang.UnsatisfiedLinkError: findLibrary 返回 null
【发布时间】:2012-02-20 17:13:54
【问题描述】:

在您的 Android JNI 应用中出现上述错误?继续阅读...

在前面,我会说我已经以自己的方式解决了这个问题,但我觉得 Android 构建系统中的某些东西(可能与 Eclipse 相关)已经坏了,我希望为其他人节省数小时的痛苦.也许其他人已经遇到过这个问题并可以评论什么对他们有用。

有一段时间,我有一个使用 NDK 开发的带有一些 JNI 代码的 Android 项目。然后,今天,我在 java 代码中更改了一些内容,然后噗,我无法再加载我的 JNI 库。它失败了,异常如下:

E/AndroidRuntime(999):java.lang.UnsatisfiedLinkError:无法加载 mylibrary:findLibrary 返回 null

我用谷歌搜索并尝试了所有方法(重建、关闭和重新启动 Eclipse 等)

什么最终解决了我的问题?在尝试再次运行之前,我从设备上实际卸载了我的应用程序。而已。在那之后,它奏效了。什么对你有用?

【问题讨论】:

  • 我看到了奇怪的行为,我不得不将 .so 文件从 \LIBS\ARMEABI 目录中复制出来,并将其放在 \LIBS 目录中以便它找到它。
  • 我的应用程序也有同样的问题,不幸的是我的一些客户收到了这个问题(我看到很多关于这个的崩溃报告)。我不知道为什么它只发生在“某些”上,但它适用于大多数。我自己也永远无法复制它。很奇怪……
  • 我的设备上有两个应用程序实例,刚刚将 sharedUserId 添加到清单中,但忘记先卸载旧版本。谢谢提醒!
  • @BitBank 你成功了!我的应用程序在模拟器上运行良好,但在手机上运行不佳,我将库复制到所有 Intel、amreabi 文件夹并且它运行正常。地狱是的。

标签: android-ndk java-native-interface


【解决方案1】:

在我的情况下,.so 库已正确加载,但找不到如下方法:

原因:java.lang.UnsatisfiedLinkError: Native method not found...

经过数小时搜索可能出现的问题后,发现应用程序仅会为生产环境引发相关错误。是的,我们使用 proguard 来混淆源代码,它会破坏 .so 库处理程序类...在将以下行添加到 proguard 规则文件之后。它开始按预期工作。

-keepclasseswithmembers,allowshrinking,allowoptimization class com.zk.android.jni.Device {
native <methods>; }

因此,如果您使用 proguard 并且遇到与我类似的问题。请检查proguard文件...

【讨论】:

    【解决方案2】:

    在您的 gradle 文件中添加以下代码

    //libs is the location of your library's folder, It varies in diffarent projects like src/main/libs etc.
    android {
      sourceSets.main {
        jniLibs.srcDir 'libs'
      }
    }
    

    因此,Android Studio 继续在 jniLibs 文件夹中查找本机库。此代码将更改 android studio 的路径以查看 libs 文件夹中的库

    【讨论】:

      【解决方案3】:

      我加了

      extern "C"
      

      在函数声明之前
      例如:

      extern "C"
      jstring
      Java_lara_myapplication_MainActivity_stringFromJNI(
                  JNIEnv *env,
          jobject /* this */) {
          std::string hello = "Hello from C++";
          return env->NewStringUTF(hello.c_str());
      }
      

      然后错误消失了

      【讨论】:

        【解决方案4】:

        如果您有一个带有 LOCAL_MODULE "libXYZ" 的本机项目,请确保将其加载为

        System.loadLibrary("XYZ");
        

        【讨论】:

        • 这适用于错误的第一部分,我现在得到 java.lang.UnsatisfiedLinkError: method_name_here
        • 这是令人难以置信的糟糕谷歌!花了我2个小时。迫不及待地想再次为 windows mobile 开发。
        【解决方案5】:

        就我而言,在制作系统应用程序时,问题与权限有关。将“.so”文件放入/system/lib//system/vendor/lib/目录后,我将默认分配的权限600修改为755,效果很好。

        【讨论】:

        • 虽然问题确实存在,但您的设置不正确。您缺少执行位,因此这在强制执行该操作的 ARM 系统上不起作用。 Android 上的普通 .so 文件权限为 755。
        • @ChrisStratton 感谢您的纠正。我没有提到它,但我使用了 755,在我实验室的一台 android 设备上默认为 600。
        • @aditya 我有类似的要求,我必须制作一个系统应用程序。我什至确实将权限更改为 777,但我得到了同样的错误,你有什么线索吗?
        【解决方案6】:

        UnsatisfiedLinkerror 已解决。通过“ndk_build”再次构建您的 .so 文件

        【讨论】:

          【解决方案7】:

          首先,检查 Eclipse 中的 libs 文件夹或 android studio 中的 jniLibs 文件夹中是否有 jni 文件。当您签入任何 svn 时,请交叉检查以签入 .so 文件。

          我的场景是在使用 Android Studio 构建时。

          当您在 android studio 中构建时,您的库 .so 文件或 (jni) 文件应位于 \src\main\jniLibs\armeabi***.so 文件夹中。

          因为这些文件将在 eclipse 中的 \libs\armeabi***.so 中。

          同时使用 eclipse 和 android studio 构建时,您必须将 build.gradle 文件修改为

          main {
                      manifest.srcFile 'AndroidManifest.xml'
                      java.srcDirs = ['src']
                      resources.srcDirs = ['src']
                      aidl.srcDirs = ['src']
                      renderscript.srcDirs = ['src']
                      res.srcDirs = ['res']
                      assets.srcDirs = ['assets']
          
                      // Fixed Issue : "android studio java.lang.unsatisfiedlinkerror: couldn't load find library returned null"
                      // Cause : For android studio : The JNI files should be placed in the /src/main/jniLibs folder.
                      // Fix : Mapping the jniLibs 's source Directories with Lib's folder
                      jniLibs.srcDirs = ['libs']
          }
          

          这里我正在使用 android studio 和 eclipse 构建项目。

          【讨论】:

          • 对不起,同样的问题
          • 你可以试试:jniLibs.srcDir "src/main/libs"
          【解决方案8】:

          我刚刚发生了这种情况,问题是设备根本没有足够的空间来安装库。我卸载了一些其他应用程序,然后它就可以工作了。

          【讨论】:

            【解决方案9】:

            以前的答案都没有解决我的问题,但确实解决了:一直以来的问题是没有必要的子目录和文件。我的 libs 文件夹中只有一个 armeabi 文件夹,其中包含正确的 .so 文件,但应该还有 3 个其他文件夹,每个文件夹中都有一个 .so 文件。还不确定其他三个(armeabi-v7a、mips 或 x86)中的哪一个是必需的,但我知道当我将 Application.mk 文件添加到与 Android.mk 相同的文件夹时,所有三个都是自动生成的文件,并确保其中包含以下行:

            APP_ABI := all
            

            对我来说,那行是里面唯一的文字。然后运行 ​​ndk-build 时,Application.mk 文件显然会导致“所有”4 个文件夹被创建,并在其中创建正确的 .so 文件。安装 Application.mk 后,我再次运行 ndk-build,然后在再次尝试之前对我的 Eclipse 项目进行了清理和清理。一切运行良好。

            【讨论】:

              【解决方案10】:

              我遇到了同样的问题,这些是我在项目中遇到的一些问题:


              1. System.load("hello-test"); 更改为System.loadLibrary("hello-test");
              2. 将 C 函数签名更改为 JNIEXPORT jstring Java_com_example_testndk_TestNDK_funcNami(JNIEnv* env, jobject thiz):这里使用 Java_&lt;java_package_name&gt;_&lt;java-class-name&gt;_&lt;function-name&gt;
              3. 将 NDK 路径添加到 local.properties,在我的情况下为 ndk.dir=&lt;my-path-to-ndk-directory&gt;;和
              4. 将我的build.gradle 更新为也包含在defaultConfig 中:ndk { moduleName "hello-test" }

              • 包名:com.example.testndk
              • Java 类名:TestNDK
              • C 源名称:hello-test.c
              • 项目结构中的JNI目录位置:AndroidProjects/TestNDK/app/src/main/jni

              IDE:Android Studio 0.8.1。

              【讨论】:

              • System.load() 用于指定实际路径和文件名时,通常使用带有短库名称的 System.loadLibrary()(无路径,并且没有“lib”前缀或“.so”后缀)
              • 对我来说 #4(包括 defaultConfig 中的“ndk”)成功了。谢谢!
              • 感谢 defaultConfig 在 gradle 中。我无法发现我的错误。
              • 感谢 defaultConfig 在 gradle 中。我无法发现我的错误。
              【解决方案11】:

              在 libs 文件夹中,我创建了一个名为 armeabi-v7a 的新文件夹,并将 .so 文件从 armeabi 复制到新文件夹。它解决了错误。

              【讨论】:

                【解决方案12】:

                如果您有一个带有“libXYZ.so”的本机项目,请确保您的设备上不存在 /system/lib/libXYZ.so。有一个痛苦的解决方法:使用

                System.load("/data/data/your.package.name/lib/libXY.so") 
                

                而不是 System.loadLibrary()

                【讨论】:

                  【解决方案13】:

                  如果您尝试在模拟器中运行您的应用,请确保您在 Run -> Run Configurations -> Target 中指定了正确的架构(您可能需要使用 Window -> Android Virtual Device 添加所需的模拟器经理)。

                  我在尝试在 Intel 模拟器中执行应用程序时遇到了同样的问题,而该应用程序使用的是为 ARM 预编译的库。

                  【讨论】:

                    【解决方案14】:

                    我也遇到了这个问题,但就我的情况而言,我在另一个项目中使用了我的库。而且我认为这不是 eclipse 或 android-ndk 的问题。

                    您可以查看这些可以导致UnsatisfiedLinkError 的提示,它对我来说很好,祝你好运:)

                    1. 必须遵循JNI接口的命名规则(你说你之前确实加载过库成功,所以你可以忽略这个)并且库必须在目录/your project/libs/armeabi/
                    2. 如果您确保上述事情都已完成,那么您必须确保您生成的库已安装到您的 app.apk 中,否则仍然无法找到该库并给你一个错误。为此,您可以右键单击您的 Eclipse 项目名称,然后进入 Build Path - Configure Build Path ,在左侧菜单中,选择Java Build Path,然后点击右侧的Order and Export标签面板,选中您的库名称之前的复选框,然后单击 确定,然后清理、重建并运行您的项目,你的库将被安装到 app.apk 中,事情就完成了。

                    编辑:

                    1. 一句话,如果你的app.apk中没有安装这个库,就会抛出UnsatisfiedLinkError,所以不能成功链接。

                    【讨论】:

                      【解决方案15】:

                      有同样的问题。 刚刚清理项目,它工作。谜团..

                      【讨论】:

                        【解决方案16】:

                        无需root设备..在模拟器上部署应用并浏览文件夹

                        【讨论】:

                        • 是的。或者在支持它的安全设备上使用调试版本和运行方式工具。
                        【解决方案17】:

                        刚刚遇到类似的问题。

                        查看您的 /data/data/your.package.name/lib 目录

                        当我在我的包目录中时,它当前显示:

                        lib -> /mismatched_uid/settings_10037/fs_1000
                        

                        可能我不小心切换了 sharedUserId,因此无法再访问该库。

                        【讨论】:

                        • 你能澄清一下吗?我也遇到了同样的错误,而你刚才说的离我很远
                        • 在我的情况下,我更改了我的 AndroidManifest 中的 sharedUiserId=".."。因此,应用程序由不同的用户运行,但文件夹/文件仍属于另一个用户。 root 后,您可以导航到 /lib 目录并使用“ls”命令显示文件属于谁。
                        • 您可以在任何手机上ls -l /data/data/your.package.name/lib,但您可能无法访问其父级。因此,您需要有根设备才能导航到该目录。
                        • 是的,没错,亚历克斯。不确定它在这种情况下是否有效,因为 lib 目录本身似乎已经更改了权限 - 但在没有植根时当然值得一试。稍微修改了一下答案。
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-02-07
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2013-11-05
                        • 1970-01-01
                        • 2014-10-26
                        相关资源
                        最近更新 更多