前几天我asked关于运行非本机OpenCV代码的UnsatisfiedLinkError
。我认为在重新安装Eclipse并关闭/重新打开所有软件包之后问题就解决了,但是在我将OpenCV代码放入现有的onCreate()
方法后,它又回来了。
我使用名为Start的活动创建了一个新的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)
同样,这是非本机代码,因此具有不满意的链接错误并没有多大意义。
答案 0 :(得分:38)
经过一番搜索后,我找到了this:
“3.如果您的应用程序项目没有JNI部分,只需将/ sdk / native / libs /中相应的OpenCV本机库复制到项目目录到文件夹libs /。”
这意味着复制\ armeabi,\ armeabi-v7a和\ x86文件夹。
“4.在您的应用程序中启用OpenCV的最后一步是在调用OpenCV API之前的Java初始化代码。例如,可以在Activity类的静态部分中完成,该部分只执行一次,然后才执行创建了类的实例:
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
}
[...]
}
现在有效!
答案 1 :(得分:8)
你应该使用
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;
}
}
};
答案 2 :(得分:7)
在大多数情况下,在调用openCV之前这样的行就足够了: “的System.loadLibrary(Core.NATIVE_LIBRARY_NAME);”
答案 3 :(得分:2)
问题是您在 OpenCV4Android 库甚至完成加载之前使用 Highgui.imread 方法。 Android调用" onCreate"加载 OpenCV4Android 库之前的方法。因此,为您的OpenCV代码创建一个单独的方法,如下所示: -
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--------");
}
}
答案 4 :(得分:2)
我在Android Studio的项目中添加了opencv。当本机文件在运行时不可用时,会发生此错误。因此,您必须在正确的位置复制本机文件。
首先在此位置jniLibs
位置创建/app/src/main/
,并使用OpenCV SDK中的jniLibs中的* .so文件(armeabi,armeabi-v7a,mips,x86)复制所有文件夹,使你的gradle插件高于0.7.2 +
答案 5 :(得分:1)
答案中的链接不起作用,我不得不在一段时间内寻找适用于我的解决方案。
我首先在类
中定义了BaseLoaderCallbackprivate 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
onCreate()
中,opencv还没有加载。最好将它放在 OpenCV已成功加载的开关案例中的onManagerConnected()
函数中。答案 6 :(得分:0)
在我的情况下,我将opencv类粘贴到错误的包名称中
我将opencv类粘贴到 com.opencv ->所有类
org.opencv ->所有类
更改此正确的软件包名称后,它将起作用。
原因-他们可能会引用“ org.opencv ..”
答案 7 :(得分:0)
我花了几个小时来解决这个问题,但找不到可行的解决方案。 这是对我有用的方法,请查看我对类似问题的回答..