![](/img/trans.png)
[英]No Implementation found for native UnsatisfiedLinkError Exception Android JNI
[英]Android JNI NDK - No implementation found
我在 Android 上有一個 libjpeg-turbo 的 JNI 實現。 應用程序的構建沒有任何問題,我可以在生成的 APK 文件中看到本機libJPEGProcessing.so
庫位於不同架構的lib
文件夾中。 但是,當通過應用程序調用本地方法時,我會收到以下“未找到實現”消息,這將導致異常:
D/dalvikvm: No JNI_OnLoad found in /system/lib/libjpeg.so 0xa4fe3dc0, skipping init
D/dalvikvm: Trying to load lib /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0
D/dalvikvm: Added shared lib /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0
D/dalvikvm: No JNI_OnLoad found in /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0, skipping init
W/dalvikvm: No implementation found for native Lcom/google/test/NativeMethods;.computeUsableDCTCoefficientsLinkedList:(Ljava/lang/String;)I
這是我在 JNI 中的方法:
extern "C" {
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
// Get jclass with env->FindClass.
// Register methods with env->RegisterNatives.
return JNI_VERSION_1_6;
}
JNIEXPORT jint JNICALL Java_com_google_test_NativeMethods_computeUsableDCTCoefficientsLinkedList
(JNIEnv *env, jobject obj, jstring javaString)
{
...
}
}
以及生成的頭文件:
extern "C" {
/*
* Class: com_google_test_NativeMethods
* Method: computeUsableDCTCoefficientsLinkedList
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_google_test_NativeMethods_computeUsableDCTCoefficientsLinkedList
(JNIEnv *, jclass, jstring);
}
Java 中的實現如下所示:
package com.google.test;
import java.util.ArrayList;
public class NativeMethods {
private String filename = null;
private int fromNative = -100;
private int numberInList = -100;
private ArrayList<DCTCoefficient> array = null;
static {
System.loadLibrary("jpeg");
System.loadLibrary("JPEGProcessing");
}
public static native int computeUsableDCTCoefficientsLinkedList(String filename);
}
這是ndk-build
Android.mk
:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_FILES := ./libjpeg-turbo/
LOCAL_MODULE := JPEGProcessing
LOCAL_CFLAGS := -Ic:\AndroidStudioProjects\Test\Test\src\main\jni\ -Ic:\libjpeg-turbo-gcc\include\
LOCAL_SRC_FILES := JPEGProcessing.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_STATIC_LIBRARIES := c:\libjpeg-turbo-gcc\lib\libjpeg.a
include $(BUILD_SHARED_LIBRARY)
在構建和編譯過程中沒有錯誤,應用程序將在 Android 設備上正常啟動。 但是,我定義了 JNI_OnLoad 方法,在 Java 類中加載本機庫后也不會調用該方法。
編輯:
我在 Gradle Console 中發現了以下警告,可能與之相關:
Android NDK: WARNING:C:/AndroidStudioProjects/Test/Test/src/main/jni/Android.mk:JPEGProcessing: non-system libraries in linker flags: c:\libjpeg-turbo-gcc\lib\libjpeg.a
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module
編輯2:
試圖在 Linux 上查看編譯后的 libJPEGProcessing.so:
nm libJPEGProcessing.so
nm: libJPEGProcessing.so: no symbols
nm -D libJPEGProcessing.so
00002004 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002004 A _edata
00002004 A _end
沒有導出的 JNI 方法和符號。 這樣對嗎?
編輯 3:
ndk-build.cmd -BV=1 APP_ABI=armeabi
:
ndk-build.cmd -B V=1 APP_ABI=armeabi
del /f/q c:\AndroidStudioProjects\Test\Test\src\main\libs\arm64-v8a\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi-v7a\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\mips\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\mips64\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\x86\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\x86_64\libJPEGProcessing.so >NUL 2>NUL
[armeabi] SharedLibrary : libJPEGProcessing.so
C:/Android/sdk/ndk-bundle/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libJPEGProcessing.so -shared --sysroot=C:/Android/sdk/ndk-bundle/build//../platforms/android-9/arch-arm -lgcc -gcc-toolchain C:/Android/sdk/ndk-bundle/build//../toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 -no-canonical-prefixes -target armv5te-none-linux-androideabi -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -lc -lm -o c:/AndroidStudioProjects/Test/Test/src/main/obj/local/armeabi/libJPEGProcessing.so
[armeabi] Install : libJPEGProcessing.so => libs/armeabi/libJPEGProcessing.so
copy /b/y "c:\AndroidStudioProjects\Test\Test\src\main\obj\local\armeabi\libJPEGProcessing.so" "c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi\libJPEGProcessing.so" > NUL
您的代碼似乎沒問題 - 我看不到任何簽名問題,而且您似乎正在以所需的方式加載庫。 但是,事實是日志說找到了庫,但它找不到您的 JNI_OnLoad 實現。 是否有可能您擁有多個版本的 libJPEGProcessing.so,而系統會找到舊版本? 當然,我不是在談論針對各種架構的不同庫。
我發現雖然APK
已編譯並正常工作,但本機庫未正確編譯並包含在lib
文件夾中的APK
文件中。
因此,我將build.gradle
更改為不使用ndk-build
,而是為項目使用預編譯的本機庫。 更改之后,本地庫包含在APK
並且一切正常:
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set libs as default directory for .so files inclusion, instead of jniLibs
jni.srcDirs = [] //disable automatic ndk-build call
}
如果有任何更改,我必須做的唯一更改是在 Android Studio 之外編譯本機庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.