JNI- java.lang.UnsatisfiedLinkError:找不到本地方法

我正在开发一个使用OpenCV的Android项目。 有些方法没有Java版本,所以我必须使用NDK在我的项目中使用它们。

这是我第一次使用NDK,所以在search一些例子之后,我写了我的代码,在我的设备上运行它,并在下面收到错误消息:

07-04 10:26:19.555 21270-21270/com.example.MyTest E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.UnsatisfiedLinkError: Native method not found: com.example.MyTest.JNIlib.readImg:()I at com.example.MyTest.JNIlib.readImg(Native Method) at com.example.MyTest.MyActivity$2.onClick(MyActivity.java:60) at android.view.View.performClick(View.java:4211) at android.view.View$PerformClick.run(View.java:17267) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4898) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) at dalvik.system.NativeStart.main(Native Method) 

我几次重新生成.so文件,并检查jni函数的命名。 我还为jni函数添加了'extern'C''包装。 但是这些解决scheme都没有奏效。

注意:我总是使用Intellij Idea来开发JAVA程序,由于Idea不支持NDK,所以我必须使用Eclipse来访问NDK,所以…这也是我第一次使用Eclipse。 我本可以犯很多愚蠢的错误。 大声笑

以下是我的c ++代码和makefile。

LocalMain.cpp

 #include <stdio.h> #include <iostream> #include <opencv2/nonfree/nonfree.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/nonfree/features2d.hpp> #include <opencv2/opencv.hpp> #include <jni.h> #include <android/log.h> #include "LocalFeature.h" using namespace cv; using namespace std; int readImg() { /* do something*/ return 0; } // JNI interface functions, be careful about the naming. extern "C" { JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jobject obj); }; JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jobject obj) { return (jint)readImg(); } 

LocalFeatures.h和LocalFeatures.cpp没有显示,但我敢肯定,问题不在他们。

Android.mk

 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := nonfree_prebuilt LOCAL_SRC_FILES := libnonfree.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := opencv_java_prebuilt LOCAL_SRC_FILES := libopencv_java.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) # Modify LOCAL_C_INCLUDES with your path to OpenCV for Android. LOCAL_C_INCLUDES:= E:/Java/libs/OpenCV-2.4.9-android-sdk/sdk/native/jni/include LOCAL_MODULE := mytest_lib LOCAL_CFLAGS := -Werror -O3 -ffast-math LOCAL_LDLIBS += -llog -ldl LOCAL_SHARED_LIBRARIES := nonfree_prebuilt opencv_java_prebuilt LOCAL_SRC_FILES := LocalMain.cpp \ LocalFeature.h \ LocalFeature.cpp include $(BUILD_SHARED_LIBRARY) 

这些.cpp文件和.mk文件在Eclipse项目中。 libmytest_lib.so,libopencv_java.so,libnonfree.so都可以正确生成。 以下.java文件位于Intellij Idea项目中。 我已经将这些.so文件复制到Idea项目中的\ lib。

JNIlib.java

 public class JNIlib { static { try { // Load necessary libraries. System.loadLibrary("opencv_java"); System.loadLibrary("nonfree"); System.loadLibrary("mytest_lib"); } catch( UnsatisfiedLinkError e ) { System.err.println("Native code library error.\n"); } } public static native int readImg(); } 

MainActivity.java的一部分

 public class MyActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2{ public View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { JNIlib.readImg(); } }; /*Other irrevelant code*/ } 

非常感谢!

Solutions Collecting From Web of "JNI- java.lang.UnsatisfiedLinkError:找不到本地方法"

遵循JonesV的build议,我从我的代码中删除了静态。 但之后,问题依然存在。

最后我debugging了我的程序,当运行到这一行时:

 System.loadLibrary("opencv_java"); 

程序抛出一个错误,而不是像我想的那样正常运行。 真是愚蠢的错误:<

现在,我发现了一个我从来没有注意到的错误。

 java.lang.UnsatisfiedLinkError: Couldn't load opencv_java: findLibrary returned null 

这意味着,没有LIBS被加载。 所以我检查了我的项目结构,发现我将.so文件放在libs /文件夹中,而不是libs / armeabi /文件夹中。

和解决scheme是在这里find: Android NDK java.lang.UnsatisfiedLinkError:findLibrary返回null由user1647750

我补充说

 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()); } 

那么错误消失了

删除static

 public static native int readImg(); 

即写这样的:

 public native int readImg(); 

如果你真的希望你的readImg()方法是静态的,你应该像下面这样声明JNI方法(使用jclass而不是jobject ):

  JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jclass obj);