不满意的链接错误 – OpenCV for Android非本机

前几天我问了一个运行非本地OpenCV代码的UnsatisfiedLinkError 。 我认为这个问题在重新安装Eclipse并closures/重新打开所有包之后解决了,但是在将OpenCV代码放入现有的onCreate()方法之后,问题又回来了。

我用一个名为Start的活动创build了一个新的Android应用程序。 然后我去了项目属性,并添加OpenCV作为一个库。 以下是活动的代码( Start.java ):

 package com.test; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import android.os.Bundle; import android.app.Activity; import android.app.AlertDialog; import android.view.Menu; public class Start extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start); Mat Image = Highgui.imread("/image.jpg"); if (Image == null) { AlertDialog ad = new AlertDialog.Builder(this).create(); ad.setMessage("Fatal error: can't open /image.jpg!"); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_start, menu); return true; } } 

这里是日志:

 08-13 12:26:14.791: E/Trace(1067): error opening trace file: No such file or directory (2) 08-13 12:26:15.191: W/dalvikvm(1067): No implementation found for native Lorg/opencv/highgui/Highgui;.imread_1:(Ljava/lang/String;)J 08-13 12:26:15.191: D/AndroidRuntime(1067): Shutting down VM 08-13 12:26:15.191: W/dalvikvm(1067): threadid=1: thread exiting with uncaught exception (group=0x40a13300) 08-13 12:26:15.201: E/AndroidRuntime(1067): FATAL EXCEPTION: main 08-13 12:26:15.201: E/AndroidRuntime(1067): java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.highgui.Highgui.imread_1:(Ljava/lang/String;)J 08-13 12:26:15.201: E/AndroidRuntime(1067): at org.opencv.highgui.Highgui.imread_1(Native Method) 08-13 12:26:15.201: E/AndroidRuntime(1067): at org.opencv.highgui.Highgui.imread(Highgui.java:324) 08-13 12:26:15.201: E/AndroidRuntime(1067): at com.test.Start.onCreate(Start.java:18) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.app.Activity.performCreate(Activity.java:5008) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.app.ActivityThread.access$600(ActivityThread.java:130) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.os.Handler.dispatchMessage(Handler.java:99) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.os.Looper.loop(Looper.java:137) 08-13 12:26:15.201: E/AndroidRuntime(1067): at android.app.ActivityThread.main(ActivityThread.java:4745) 08-13 12:26:15.201: E/AndroidRuntime(1067): at java.lang.reflect.Method.invokeNative(Native Method) 08-13 12:26:15.201: E/AndroidRuntime(1067): at java.lang.reflect.Method.invoke(Method.java:511) 08-13 12:26:15.201: E/AndroidRuntime(1067): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 08-13 12:26:15.201: E/AndroidRuntime(1067): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 08-13 12:26:15.201: E/AndroidRuntime(1067): at dalvik.system.NativeStart.main(Native Method) 

再次,这是非本地代码,所以有一个不满意的链接错误没有太大的意义。

Solutions Collecting From Web of "不满意的链接错误 – OpenCV for Android非本机"

经过一番search之后,我发现这个 :

“3.如果您的应用程序项目没有JNI部分,只需将相应的OpenCV本机库从/ sdk / native / libs /复制到您的项目目录到文件夹libs /。

所以这意味着复制\ armeabi,\ armeabi-v7a和\ x86文件夹。

“4.在您的应用程序中启用OpenCV的最后一步是调用OpenCV API之前的Java初始化代码,例如,可以在Activity类的静态部分完成,该部分只会执行一次,类创build:

 static { if (!OpenCVLoader.initDebug()) { // Handle initialization error } } 

或者,你可以把它放在onCreate方法中:

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_load_image); if (!OpenCVLoader.initDebug()) { // Handle initialization error } [...] } 

现在它工作!

你应该使用

 if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack)) { Log.e("TEST", "Cannot connect to OpenCV Manager"); } 

在OnCreate()和使用

 private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { Mat Image = Highgui.imread("/image.jpg"); if (Image == null) { AlertDialog ad = new AlertDialog.Builder(this).create(); ad.setMessage("Fatal error: can't open /image.jpg!"); } } break; default: { super.onManagerConnected(status); } break; } } }; 

在大多数情况下,在调用openCV之前,这样的一行就足够了:“System.loadLibrary(Core.NATIVE_LIBRARY_NAME);”

问题是,在OpenCV4Android库甚至完成加载之前,您正在使用Highgui.imread方法。 Android在加载OpenCV4Android库之前调用“onCreate”方法。 因此,为您的OpenCV代码创build一个单独的方法是这样的: –

 public class Start extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_start, menu); return true; } public void readImage { Mat Image = Highgui.imread("/image.jpg"); if(Image=null) { Log.i("Start", "--------Image Cannot be Loaded--------"); else if(!Image=null) { Log.i("Start", "--------Image Loaded Successfully--------"); } 

}

我在Android Studio中的项目中添加了opencv。 本机文件在运行时不可用时发生此错误。 所以你必须复制本地文件在正确的位置。

首先在这个位置/app/src/main/ location创buildjniLibs,并从OpenCV SDK的jniLibs中复制带有* .so文件(armeabi,armeabi-v7a,mips,x86)的所有文件夹,并将上面的gradle插件0.7.2+

在这里输入图像说明

答案中的链接不起作用,我不得不挖掘一段时间的解决scheme,为我工作。

我首先在类中定义了一个BaseLoaderCallback

 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { Log.i(TAG, "OpenCV loaded successfully"); // any immediate code for using OpenCV } break; default: { super.onManagerConnected(status); } break; } } }; 

然后在onResume函数我有:

 @Override public void onResume() { super.onResume(); if (!OpenCVLoader.initDebug()) { Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization"); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback); } else { Log.d(TAG, "OpenCV library found inside package. Using it!"); mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } } 

确保以下内容

1.您正在根据您的版本更改OPENCV_VERSION_3_0_0

  1. 在加载之前不要运行任何opencv库。 即使在onCreate() ,opencv尚未加载。 最好把它放在OpenCV成功加载的开关柜的onManagerConnected()函数中。