AndroidRuntime 导致:java.lang.unsatisfiedLinkError:无法加载 tfp_jni:findLibrary 返回 null
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18992329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AndroidRuntime Caused by: java.lang.unsatisfiedLinkError: Couldn't load tfp_jni: findLibrary returned null
提问by Patricia
So, it looks like there are a lot of issues like mine out there but not sure any of them are related to my issue. OK. I have an Android project that uses an SDK as a referenced library. The SDK contains C++, so I am using the android-ndk-r9 library. The SDK that I reference in my Android project is a JNI library (Oooooo - scary stuff). Oh yeah, don't let me forget to mention armeabi-v7a (which appears to be another scary subject). My error occurs when this line is executed:
所以,看起来有很多像我这样的问题,但不确定它们是否与我的问题有关。好的。我有一个使用 SDK 作为引用库的 Android 项目。SDK 包含 C++,所以我使用的是 android-ndk-r9 库。我在我的 Android 项目中引用的 SDK 是一个 JNI 库(Oooooo - 可怕的东西)。哦,是的,不要让我忘记提及 armeabi-v7a(这似乎是另一个可怕的主题)。执行此行时发生我的错误:
System.loadLibrary("tfp_jni");
tfp_jni is really a libtfp_jni.so file under the armeabi-v7a folder in libs folder of my SDK library project. That SDK library project contains an Android.mk file. I do not think the code is getting in there. But here is the contents of that .mk file:
tfp_jni 实际上是我的 SDK 库项目的 libs 文件夹中 armeabi-v7a 文件夹下的 libtfp_jni.so 文件。该 SDK 库项目包含一个 Android.mk 文件。我不认为代码在那里。但这是该 .mk 文件的内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tfp-prebuilt
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libtfp_jni.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
Then in my Android project, I have a jni folder containing an Android.mk and an Application.mk. Here are the contents:
然后在我的 Android 项目中,我有一个 jni 文件夹,其中包含一个 Android.mk 和一个 Application.mk。以下是内容:
Android.mk
安卓.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES:=on
OPENCV_INSTALL_CAMERA:=off
include $(INNERID_ANDROID_ROOT)/Android.mk
include $(OPENCV_ANDROID_ROOT)/sdk/native/jni/OpenCV.mk
Application.mk
应用程序.mk
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-14
Environment Variables
环境变量
Paths and Symbols - Includes
路径和符号 - 包括
All other tabs are empty except for the Source Location and Output Location, which displays the project folder.
除了显示项目文件夹的源位置和输出位置之外,所有其他选项卡都是空的。
Android project & Preferences
Android 项目和首选项
I have tried various other answers from the similar questions on Stackoverflow with no success. Please let me know if there is anything else you need to see and I'll provide the additional information as soon as possible.
我已经尝试了 Stackoverflow 上类似问题的各种其他答案,但没有成功。如果您还有什么需要查看的,请告诉我,我会尽快提供其他信息。
New Image
新图片
Correction! The apk is in the verify-demo-nolic project /bin folder. The Referenced Library tfp_java.jar is the SDK library project. You can see from Finder that the .so file is in libs. Does this help?
更正!apk 位于 verify-demo-nolic 项目 /bin 文件夹中。Referenced Library tfp_java.jar 是 SDK 库项目。您可以从 Finder 中看到 .so 文件在 libs 中。这有帮助吗?
采纳答案by Chris Stratton
A number of things must occur for the linkage to work
必须发生许多事情才能使链接起作用
The native library must be compiled to an .so file for the appropriate ABI(s) - this is typically accomplished via the
ndk-build
script/batch file, though it can also be done using a generated stand alone toolchain. IDE projects may want to configure running this as a custom build step.The native library must get packaged in the application .apk. If it was built from a jni/ folder under an application project directory, then
ndk-build
probably copied it into an ABI-appropriate subdirectory of the libs/ folder of the project. However, if the native library belongs to a distinct Android library, extra steps may be required. In particular, a .so cannot be obtained by the build system from a library .jarand so one associated with library code must either by explicitly copied under the libs/ folder of the client project, or else found by referencing a library project directory tree (not a lonely .jar) which includes it.The installer on the device must decide that one of the .so files contained in the .apk is appropriate for the device's ABI (architecture) and copy it out of the .apk into the install directory for use.
The runtime linkage names of the jni functions (downstream of any compiler name-mangling) must match those which the VM is looking for. Typically, problems here come up from not correctly encoding the java fully qualified class name in the native function name. The
javah
tool is intended to help avoid such mistakes, though with care it can be done manually.
必须将本机库编译为适合 ABI 的 .so 文件 - 这通常是通过
ndk-build
脚本/批处理文件完成的,但也可以使用生成的独立工具链来完成。IDE 项目可能希望将此配置为自定义构建步骤。本机库必须打包在应用程序 .apk 中。如果它是从应用程序项目目录下的 jni/ 文件夹构建的,则
ndk-build
可能将其复制到项目的 libs/ 文件夹的 ABI 适当子目录中。 但是,如果本机库属于不同的 Android 库,则可能需要额外的步骤。特别是,构建系统无法从库 .jar 中获取.so ,因此与库代码相关的 .so必须通过显式复制到客户端项目的 libs/ 文件夹下,或者通过引用库项目目录树找到(不是一个孤独的 .jar),其中包括它。设备上的安装程序必须确定 .apk 中包含的 .so 文件之一适合设备的 ABI(架构),并将其从 .apk 复制到安装目录中以供使用。
jni 函数的运行时链接名称(任何编译器名称修改的下游)必须与 VM 正在寻找的名称相匹配。通常,这里的问题来自未正确编码本地函数名称中的 java 完全限定类名称。该
javah
工具旨在帮助避免此类错误,但可以小心地手动完成。
Each of these steps presents a potential breakdown, so debugging an unsatisfied link can be approached by trying to find the first stage at which the .so file goes missing.
这些步骤中的每一个都存在潜在的故障,因此可以通过尝试找到 .so 文件丢失的第一个阶段来调试不满意的链接。