繁体   English   中英

使用OpenCV 2.4.2的Android UnsatisfiedLinkError

[英]Android UnsatisfiedLinkError with OpenCV 2.4.2

只是想尝试一个简单的openCV android程序。 按照此处说明下载并安装OpenCV for Android,并将OpenCV Library 2.4.2添加为我自己的android项目的库项目,如指令状态。

但是当我编译标准的“Hello World Program”时,如下所示,如果我包含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设置。

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

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 Manager”的想法。 这使得用户必须在应用程序运行之前手动安装多个软件包。

解决方案是在@Jason回答中使用OpenCV Manager。 这里官方文档也详细解释了这一点。

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

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

  • 你的应用程序apk大小会小很多:

    • 一个简单的opencv应用程序每个应用程序大约约400KB + OpenCV Manager大约800KB +为您的设备架构编译的OpenCV库大约12MB。
    • 使用传统的静态链接,您设备中的每个 opencv应用程序至少约为25MB。
    • 当然,这些尺寸取决于您放置在应用程序中的内容量...

即便如此,如果您希望以传统的方式部署应用程序, 静态链接您可以在此处阅读说明

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM