不满意的链接错误 - 适用于 Android 非原生的 OpenCV
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11939192/
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
Unsatisfied Link Error - OpenCV for Android Non-native
提问by 1''
A few days ago I askedabout an UnsatisfiedLinkError
from running non-native OpenCV code. I thought the problem was solved after reinstalling Eclipse and closing/reopening all the packages, but it's back again after I put the OpenCV code into the existing onCreate()
method.
几天前,我询问了一个UnsatisfiedLinkError
来自运行非本地 OpenCV 代码的问题。我以为问题在重新安装 Eclipse 并关闭/重新打开所有包后解决了,但在我将 OpenCV 代码放入现有onCreate()
方法后又回来了。
I created a new Android application with an activity called Start. I then went to project properties and added OpenCV as a library. Here's the code for the activity (Start.java
):
我创建了一个新的 Android 应用程序,其中包含一个名为 Start 的活动。然后我转到项目属性并将 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;
}
}
And here's the log:
这是日志:
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.access0(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)
Again, this is non-native code, so having an Unsatisfied Link Error doesn't make much sense.
同样,这是非本地代码,因此出现 Unsatisfied Link Error 没有多大意义。
回答by 1''
After a bunch of searching, I found this:
经过一番搜索,我发现了这个:
"3. If your application project doesn't have a JNI part, just copy the corresponding OpenCV native libs from /sdk/native/libs/ to your project directory to folder libs/."
“3.如果你的应用项目没有JNI部分,只需将对应的OpenCV原生库从/sdk/native/libs/复制到你的项目目录到文件夹libs/。”
So that means copy the \armeabi, \armeabi-v7a, and \x86 folders.
所以这意味着复制 \armeabi、\armeabi-v7a 和 \x86 文件夹。
"4. The last step of enabling OpenCV in your application is Java initialization code before call to OpenCV API. It can be done, for example, in the static section of the Activity class, which gets executed only once, before any instance of the class is created:
"4. 在你的应用程序中启用 OpenCV 的最后一步是调用 OpenCV API 之前的 Java 初始化代码。例如,它可以在 Activity 类的静态部分中完成,它只会在任何实例之前执行一次创建类:
static {
if (!OpenCVLoader.initDebug()) {
// Handle initialization error
}
}
Alternatively, you can put it inside the onCreate method:
或者,您可以将它放在 onCreate 方法中:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load_image);
if (!OpenCVLoader.initDebug()) {
// Handle initialization error
}
[...]
}
Now it works!
现在它起作用了!
回答by sdyy
you should use
你应该使用
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
{
Log.e("TEST", "Cannot connect to OpenCV Manager");
}
in OnCreate() And use
在 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;
}
}
};
回答by DanielTheRocketMan
In most situations, a line like this before calling openCV is enough: "System.loadLibrary(Core.NATIVE_LIBRARY_NAME);"
在大多数情况下,在调用 openCV 之前这样一行就足够了:“System.loadLibrary(Core.NATIVE_LIBRARY_NAME);”
回答by Ajay S
I was adding opencv in my project in Android Studio. This error occurs when native files are not available at run time. So you have to copy native files at correct location.
我在 Android Studio 的项目中添加了 opencv。当本机文件在运行时不可用时会发生此错误。因此,您必须在正确的位置复制本机文件。
First create the jniLibs
at this location /app/src/main/
location and copy the all the folder with *.so files (armeabi, armeabi-v7a, mips, x86) in the jniLibs from the OpenCV SDK and make your gradle plugin above 0.7.2+
首先jniLibs
在这个位置创建/app/src/main/
并复制所有带有 *.so 文件(armeabi、armeabi-v7a、mips、x86)的文件夹来自 OpenCV SDK 的 jniLibs,并使你的 gradle 插件高于 0.7.2+
回答by h0tSPR1NG
The problem is that you are using Highgui.imreadmethod before the OpenCV4Androidlibrary even finishes loading. Android calls the "onCreate" method before loading the OpenCV4Androidlibrary. So, create a separate method for your OpenCV code like this :-
问题是您在OpenCV4Android库完成加载之前使用了Highgui.imread方法。Android 在加载OpenCV4Android库之前调用“onCreate”方法。因此,为您的 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--------");
}
}
}
回答by Binil Jacob
The link in the answer was not working and i had to dig around for sometime for the solution that worked for me.
答案中的链接不起作用,我不得不四处寻找对我有用的解决方案。
I first had a BaseLoaderCallback defined in the class
我首先在类中定义了一个 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;
}
}
};
Then in onResume function i had:
然后在 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);
}
}
Make sure of the following
确保以下几点
1.You are changing the OPENCV_VERSION_3_0_0 as per your version
1.您正在根据您的版本更改 OPENCV_VERSION_3_0_0
- Not to run any opencv library before loading. Even in
onCreate()
, opencv has not yet loaded. Better to put it in theonManagerConnected()
function in the switch case where OpenCV has loaded successfully.
- 在加载之前不要运行任何 opencv 库。即使在
onCreate()
,opencv 还没有加载。最好把它放在OpenCV 加载成功onManagerConnected()
的 switch 情况下的函数中。
回答by Ranjith Kumar
In my case I paste the opencv classes in wrong package name
在我的情况下,我将 opencv 类粘贴到错误的包名中
Wrong one
错了
I paste the opencv classes into com.opencv-> all classes
我将 opencv 类粘贴到com.opencv-> 所有类
Correct one
正确一个
org.opencv-> all classes
org.opencv-> 所有类
After change this right package name it will works.
更改此正确的包名称后,它将起作用。
Reason - they may refer "org.opencv.."
原因 - 他们可能会提到“org.opencv..”