2012-07-23 67 views
14

只是想做一个简单的openCV android程序。下载并安装OpenCV for Android,遵循instructions here,并将OpenCV Library 2.4.2添加为我自己的Android项目的库项目,如指令状态。Android UnsatisfiedLinkError与OpenCV 2.4.2

但是,当我编译标准的“Hello World程序”时,如下所示, 如果包含Mat mat = new Mat();行,则会失败,但是否则成功。

package com.example; 

import org.opencv.core.Mat; 

import android.app.Activity; 
import android.os.Bundle; 

public class HelloAndroidActivity extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     Mat mat = new Mat(); 
    } 
} 

这里的堆栈跟踪它打印出:

07-23 09:59:43.835: E/AndroidRuntime(8222): FATAL EXCEPTION: main 
07-23 09:59:43.835: E/AndroidRuntime(8222): java.lang.UnsatisfiedLinkError: n_Mat 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at org.opencv.core.Mat.n_Mat(Native Method) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at org.opencv.core.Mat.<init>(Mat.java:181) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at com.example.HelloAndroidActivity.onCreate(HelloAndroidActivity.java:15) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.app.Activity.performCreate(Activity.java:4538) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2161) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2240) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.app.ActivityThread.access$600(ActivityThread.java:139) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.os.Handler.dispatchMessage(Handler.java:99) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.os.Looper.loop(Looper.java:154) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at android.app.ActivityThread.main(ActivityThread.java:4977) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at java.lang.reflect.Method.invoke(Method.java:511) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
07-23 09:59:43.835: E/AndroidRuntime(8222):  at dalvik.system.NativeStart.main(Native Method) 

有两点需要注意:我并没有直接使用任何原生在此代码(像这里其他一些问题)和旧的OpenCV 2.3 .x库在使用相同方法之前工作得很好。两个Android项目都有相同的目标和支持的API设置。

+0

你已经放置了这个库“org.opencv.core.Mat”。确保这个jar文件在libs文件夹中。 – 2012-07-23 14:12:14

+1

添加此代码解决了我的问题。 'static {System.loadLibrary(“opencv_java3”); }' – 2016-07-14 10:47:42

回答

19

想通了。没有静态链接库。如果您使用此代码,它可以工作。

package com.example; 

import org.opencv.android.BaseLoaderCallback; 
import org.opencv.android.LoaderCallbackInterface; 
import org.opencv.android.OpenCVLoader; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 

public class HelloAndroidActivity extends Activity 
{ 

    final String TAG = "Hello World"; 

private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { 
@Override 
public void onManagerConnected(int status) { 
    switch (status) { 
     case LoaderCallbackInterface.SUCCESS: 
     { 
     Log.i(TAG, "OpenCV loaded successfully"); 
     // Create and set View 
     setContentView(R.layout.main); 
     } break; 
     default: 
     { 
     super.onManagerConnected(status); 
     } break; 
    } 
    } 
}; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    Log.i(TAG, "onCreate"); 
    super.onCreate(savedInstanceState); 

    Log.i(TAG, "Trying to load OpenCV library"); 
    if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack)) 
    { 
     Log.e(TAG, "Cannot connect to OpenCV Manager"); 
    } 
} 
} 

但是,不太喜欢这个“OpenCV管理器”的想法。这使得用户必须在应用程序运行之前手动安装多个软件包。

+0

我的问题也是一样的..仍然在同样的错误挣扎..你可以帮助我更多的解决方案? – Rekha 2012-08-31 09:38:06

+1

您是否尝试过使用我的代码? – Jason 2012-09-04 21:36:43

+1

不,我没有尝试过你的代码..但现在我的问题解决了..我的错误是真的很傻...这是我已经定义了马特m =新的马特(),在调用库之前..所以它给了错误..但它是不明显的2天.. – Rekha 2012-09-05 04:16:54

3

解决的办法是要么像在@Jason回答这是关于使用OpenCV管理器。在official documentation here上也有详细的解释。

但是就像@Jason说的那样,“让用户在应用程序工作前必须手动安装多个软件包”。虽然这是事实,OpenCV的经理有例如像一些优势:

  • 如果OpenCV的更新时,用户只需要更新管理器/库。使用管理器的应用程序可以保持不变。

  • 您的应用程序APK尺寸将变小很多:

    • 一个简单的OpenCV的应用将是约〜400KB针对每个应用程序+〜800KB的OpenCV的经理+〜12MB的OpenCV库编译为您的设备架构。
    • 与传统的静态链接每一个你的设备中的opencv应用程序将至少〜25MB。
    • 这些大小取决于偏离航线,对东西你把你的应用程序内的量...

即便如此,如果你希望部署应用程序的传统方式,静态链接you can read the instructions here

+5

“如果OpenCV更新,用户只需要更新管理器/库。”这可能是一件坏事。 您希望保持对您正在使用的版本的控制,否则没有延迟期来测试您的应用是否适用于最新版本。基本质量保证...... – pablisco 2013-05-14 10:57:13

+0

诚然,我没有跟踪最近的发展,但应该有一种机制让应用程序控制它们兼容的版本范围。如果没有,这是一个问题。 – 2013-05-14 11:23:17

+1

另一种方法是针对4个目标CPU架构中的每一个(或者只有一个,x86和mips不是扩展的)中的每一个都有多个目标APK。这只会给4mb开销,这应该没问题。 – pablisco 2013-05-14 11:53:06

2
static{System.loadLibrary("opencv_java3"); } //the name of the .so file, without the 'lib' prefix 

您可以在您的活动的任何位置静态加载打开的cv库。 搜索jniLibs文件夹中的.so文件,并将其复制/粘贴为“loadLibrary”方法的参数,而不使用lib前缀。