使用新 gradle 的带有 Android studio 1.3+ 的 OpenCv - 未定义的参考 [英] OpenCv with Android studio 1.3+ using new gradle - undefined reference

查看:31
本文介绍了使用新 gradle 的带有 Android studio 1.3+ 的 OpenCv - 未定义的参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Android Studio 1.3+ 和新的 ndk 支持下使用原生 OpenCv 2.4.11(3.0.0 也可以)时遇到问题.所有关于 .mk 文件的教程,但我想将它与新的实验 gradle 一起使用.
使用 Kiran answer Android Studio 中的 OpenCV我在java中工作得很好.我也改变了
gradle-wrapper.properties:

distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip

build.gradle(应用程序):

classpath 'com.android.tools.build:gradle-experimental:0.2.0'



build.gradle(模块):

应用插件:'com.android.model.application'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.0"defaultConfig.with {applicationId = "android.overloaded.nativetestv4"minSdkVersion.apiLevel = 18targetSdkVersion.apiLevel = 23版本代码 = 1版本名称 = "1.0"}}android.ndk{模块名称 = "我的模块"ldLibs += ['日志']cppFlags += "-std=c++11"cppFlags += "-fexceptions"cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]//添加了zstl = "stlport_static"//"gnustl_shared"改为stlport static}android.buildTypes {释放 {minifyEnabled = falseproguardFiles += file('proguard-rules.pro')}}android.productFlavors {//添加所有productFlavors代码创建(手臂"){ndk.with {abiFilters += "armeabi"文件 curDir = 文件('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi\\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(armv7"){ndk.with {abiFilters += "armeabi-v7a"文件 curDir = 文件('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi-v7a\\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(胖"){}}依赖{编译文件树(包括:['*.jar'],目录:'libs')编译'com.android.support:appcompat-v7:23.0.0'编译项目(':openCVLibrary2411')}

通过此更改,我可以在 jni 文件夹下的 c++ 文件中调用我的本机虚拟函数.CLion 还支持 #include <opencv2/core/core.hpp> 和其他人...当我声明 cv::Mat mat;给我这个错误:

链接 libmymodule.so 时链接器失败.C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:278: 错误:未定义引用'cv::fastFree(void*)'C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:367:错误:未定义对'cv::Mat::deallocate()'的引用collect2.exe:错误:ld 返回 1 个退出状态

c++ 代码:

#include #include <向量>#include <字符串>#include "helpers.h"#include //这是CLion支持的#include #include 使用命名空间标准;外部C"{JNIEXPORT jstring JNICALLJava_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass 类型) {简历::垫子;//导致错误字符串 s = "Cpp v1 - 成功";返回 env->NewStringUTF(s.data());}}

更新

- 在 ldLibs
中添加了z"- 添加了 android.productFlavors 块

现在编译成功,应用程序启动了第二个然后崩溃了这个消息
事件日志:

IllegalArgumentException:启动本机调试会话时出错:无法在设备 huawei-huawei_y530_u00-64a6513ccd8e 上找到 android.overloaded.nativetestv4 的进程

调试信息:

重新启动ADB集成并重试等待进程:android.overloaded.nativetestv4设备外壳命令:run-as android.overloaded.nativetestv4 mkdir -p/data/data/android.overloaded.nativetestv4/lldb/bin设备外壳命令: cat/data/local/tmp/lldb-server |run-as android.overloaded.nativetestv4 sh -c 'cat >/data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server;chmod 700/data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server'设备外壳命令:rm/data/local/tmp/lldb-server设备外壳命令: cat/data/local/tmp/start_lldb_server.sh |run-as android.overloaded.nativetestv4 sh -c 'cat >/data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh;chmod 700/data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh'设备外壳命令:rm/data/local/tmp/start_lldb_server.sh现在启动本机调试会话启动本机调试会话时出错:java.lang.IllegalArgumentException:无法在设备 huawei-huawei_y530_u00-64a6513ccd8e 上找到 android.overloaded.nativetestv4 的进程

日志:

A/libc:致命信号 11 (SIGSEGV) at 0x00000000 (code=1), thread 3077 (ed.nativetestv4)

解决方案

经过几周的痛苦之后,我成功了.这是我针对 Android Studio 1.3.1、OpenCv 2.4.11 的正确代码.首先,您应该执行此操作 Android Studio 中的 OpenCV(不要为项目和 opencv 提取文件夹使用包含空格的路径)然后,对于本机的 opencv:

gradle-wrapper.properties:

distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip

build.gradle(应用程序):

classpath 'com.android.tools.build:gradle-experimental:0.2.0'

build.gradle(module):

应用插件:'com.android.model.application'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.0"defaultConfig.with {applicationId = "android.overloaded.nativetestv4"minSdkVersion.apiLevel = 18targetSdkVersion.apiLevel = 23版本代码 = 1版本名称 = "1.0"}}android.ndk{模块名称 = "我的模块"ldLibs += ['日志']cppFlags += "-std=c++11"cppFlags += "-fexceptions"cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()//ldFlags += linkOptldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]//, "ibopencv_core"stl = "gnustl_shared"//"gnustl_static"//"gnustl_shared"//"stlport_static"}android.buildTypes {释放 {minifyEnabled = falseproguardFiles += file('proguard-rules.pro')}}android.productFlavors {创建(手臂"){ndk.with {abiFilters += "armeabi"文件 curDir = 文件('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi\\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(armv7"){ndk.with {abiFilters += "armeabi-v7a"文件 curDir = 文件('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi-v7a\\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(x86"){ndk.with {abiFilters += "x86"}}创建(mips"){ndk.with {abiFilters += "mips"}}创建(胖"){}}}依赖{编译文件树(包括:['*.jar'],目录:'libs')编译'com.android.support:appcompat-v7:23.0.0'编译项目(':openCVLibrary2411')}

.cpp

#include #include <向量>#include <字符串>#include "helpers.h"#include 使用命名空间标准;#ifdef __cplusplus外部C"{#万一JNIEXPORT jstring JNICALLJava_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass 类型) {cv::Mat mat(33,22, 1);string s = "Cpp v1 - succ,rows#:" + Helpers::ToStringNum(mat.rows);Helpers::Log(s);返回 env->NewStringUTF(s.data());}}

.java

package android.overloaded.nativetestv4;导入 android.support.v7.app.AppCompatActivity;导入 android.os.Bundle;导入 android.view.Menu;导入 android.view.MenuItem;导入 android.widget.TextView;导入 android.widget.Toast;公共类 MainActivity 扩展了 AppCompatActivity{静止的 {System.loadLibrary("mymodule");}public static native String FuncV1();@覆盖protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Toast.makeText(this, FuncV1(), Toast.LENGTH_LONG).show();((TextView)findViewById(R.id.txtInfo)).setText(FuncV1());}

针对 Android Studio 1.5.1、OpenCV 3.1 的更新
1. 首先你应该这样做 Android Studio 中的 OpenCV(不要使用包含白色的路径空间,用于项目和 opencv 提取文件夹),之后你应该有正常工作的 Java 应用程序
2. 修改项目根目录下的build.gradle:

buildscript {存储库{jcenter()}依赖{类路径com.android.tools.build:gradle-experimental:0.4.0"//注意:不要将您的应用程序依赖项放在这里;他们属于//在单独的模块 build.gradle 文件中}}所有项目{存储库{jcenter()}}任务清理(类型:删除){删除 rootProject.buildDir}

  1. 更改 gradle-wrapper.properties:

<块引用>

distributionBase=GRADLE_USER_HOME分布路径=包装器/distszipStoreBase=GRADLE_USER_HOMEzipStorePath=wrapper/distsdistributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip

  1. 更改 opencv 模块中的 build.gradle:

    <块引用>

    应用插件:'com.android.model.library'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.2"defaultConfig.with {minSdkVersion.apiLevel = 11targetSdkVersion.apiLevel = 23}}android.buildTypes {释放 {minifyEnabled = falseproguardFiles.add(file("proguard-rules.txt"))}}}

  2. 更改应用模块中的 build.gradle:

    <块引用>

    应用插件:'com.android.model.application'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.2"defaultConfig.with {applicationId = "android.overloaded.opencv31v1"//包名minSdkVersion.apiLevel = 11targetSdkVersion.apiLevel = 23版本代码 = 1版本名称 = "1.0"}}android.ndk {moduleName = "native"//C++ 模块的名称,用于 System.loadLibrary("native")cppFlags.add("-std=c++11")//添加规定以允许 C++11 功能cppFlags.add("-fexceptions")//你的 OpenCV 目录!!!cppFlags.add("-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString())ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])stl = "gnustl_shared"}android.buildTypes {释放 {minifyEnabled = falseproguardFiles.add(file("proguard-rules.txt"))}}android.productFlavors {创建(手臂"){ndk.with{abiFilters.add("armeabi")文件 curDir = 文件('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi\\"ldLibs.add(libsDir + "libopencv_core.a")ldLibs.add(libsDir + "libopencv_highgui.a")ldLibs.add(libsDir + "libopencv_imgproc.a")ldLibs.add(libsDir + "libopencv_java3.so")ldLibs.add(libsDir + "libopencv_ml.a")}}创建(armv7"){ndk.with {abiFilters.add("armeabi-v7a")文件 curDir = 文件('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi-v7a\\"ldLibs.add(libsDir + "libopencv_core.a")ldLibs.add(libsDir + "libopencv_highgui.a")ldLibs.add(libsDir + "libopencv_imgproc.a")ldLibs.add(libsDir + "libopencv_java3.so")ldLibs.add(libsDir + "libopencv_ml.a")ldLibs.add(libsDir + "libopencv_ts.a")}}}android.sources{主要的{jni{来源{srcDirs += ['src/main/jniMy']}}}}}依赖{编译文件树(目录:libs",包括:[$/*.jar/$])compile "com.android.support:appcompat-v7:23.1.1"//不要使用23.2.0编译项目(:openCVLibrary310")}

  3. 创建目录 app/src/main/jniMy,这是你的 .cpp 文件的地方

  4. 可选择在 jniMy 中创建文件 chelper.c,使用以下代码:

    <块引用>

    #ifndef OPENCV31V1_CHELPER_H#define OPENCV31V1_CHELPER_H#include #include <向量>#include <字符串>#include #include 使用命名空间标准;类助手{民众:模板 静态字符串 ToS​​tringNum(T tNumber){ostringstream ostrStream;ostrStream<

  5. 在 jniMy 中创建文件 native_exporter.cpp,代码如下:

    <块引用>

    #include #include <字符串>#include #include "chelper.h"外部C"{JNIEXPORT jstring JNICALLJava_android_overloaded_opencv31v1_MainActivity_FuncV1(JNIEnv *env,jclass 类型) {cv::Mat mat(33,22, CV_32FC2);string s = "Cpp v1 - succ,rows#:" +Helpers::ToStringNum(mat.rows);Helpers::Log(s);自动 i = 5;for (int i2 : {1,3,5}){Helpers::Log(Helpers::ToStringNum(i2));}返回 env->NewStringUTF(s.data());}}

  6. MainActivity.java 中的代码:

    <块引用>

    package android.overloaded.opencv31v1;导入 android.os.Bundle;导入 android.support.v7.app.AppCompatActivity;导入 android.util.Log;导入 android.view.SurfaceView;导入 android.widget.TextView;导入 android.widget.Toast;导入 org.opencv.android.CameraBridgeViewBase;导入 org.opencv.core.CvType;导入 org.opencv.core.Mat;公共类 MainActivity 扩展 AppCompatActivity 实现 CameraBridgeViewBase.CvCameraViewListener2{private static void Log(String sMsg){Log.i("My", "MainActivity." + sMsg );}静止的{System.loadLibrary("opencv_java3");System.loadLibrary("本机");}公共本机字符串 FuncV1();JavaCameraViewCustom2 _javaCameraView;//类似于JavaCameraView@覆盖protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if(getSupportActionBar() != null)getSupportActionBar().hide();字符串 sRes = FuncV1();Toast.makeText(this, sRes, Toast.LENGTH_LONG).show();((TextView)findViewById(R.id.txtInfo)).setText(sRes);_javaCameraView = (JavaCameraViewCustom2)findViewById(R.id.cameraView);_javaCameraView.setVisibility(SurfaceView.VISIBLE);_javaCameraView.setCvCameraViewListener(this);}@覆盖受保护的无效 onResume(){super.onResume();_javaCameraView.enableView();}@覆盖受保护的无效 onPause(){super.onPause();_javaCameraView.disableView();}垫_imgBgrTemp;@覆盖public void onCameraViewStarted(int width, int height){_imgBgrTemp = new Mat(height,width, CvType.CV_8UC4);}@覆盖公共无效 onCameraViewStopped(){_imgBgrTemp.release();}@覆盖公共垫 onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame){_imgBgrTemp = inputFrame.rgba();返回_imgBgrTemp;}}

Android Studio 会要求你更换 jdk,也会安装新的 gradle,你应该按照它的要求去做.

I'm having trouble using native OpenCv 2.4.11 (3.0.0 is also ok) with Android Studio 1.3+, with new ndk support. All tutorials about .mk files, but I want to use it with new experimental gradle.
Using Kiran answer OpenCV in Android Studio I achived to work fine in java. Also I have changed
gradle-wrapper.properties:

distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip

build.gradle(application):

classpath 'com.android.tools.build:gradle-experimental:0.2.0'



build.gradle(module):

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.0"

        defaultConfig.with {
            applicationId = "android.overloaded.nativetestv4"
            minSdkVersion.apiLevel = 18
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
    }

    android.ndk{
        moduleName = "mymodule"
        ldLibs += ['log']
        cppFlags += "-std=c++11" 
        cppFlags += "-fexceptions"
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()

        ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"] //added z
        stl = "stlport_static"//"gnustl_shared" changed to stlport static
    }

    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles += file('proguard-rules.pro')
        }
    }
    android.productFlavors { //added all productFlavors code
        create("arm") {
            ndk.with {
                abiFilters += "armeabi"
                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi\\" //"-L" +
                ldLibs += libsDir + "libnative_camera_r4.3.0.so"
                ldLibs += libsDir + "libopencv_contrib.a"
                ldLibs += libsDir + "libopencv_core.a"
                ldLibs += libsDir + "libopencv_highgui.a"
                ldLibs += libsDir + "libopencv_imgproc.a"
                ldLibs += libsDir + "libopencv_info.so"
                ldLibs += libsDir + "libopencv_java.so"
                ldLibs += libsDir + "libopencv_legacy.a"
                ldLibs += libsDir + "libopencv_ml.a"
                ldLibs += libsDir + "libopencv_ts.a"
            }
        }
        create("armv7") {
            ndk.with {
                abiFilters += "armeabi-v7a"
                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi-v7a\\" //"-L" +

               ldLibs += libsDir + "libnative_camera_r4.3.0.so"
               ldLibs += libsDir + "libopencv_contrib.a"
               ldLibs += libsDir + "libopencv_core.a"
               ldLibs += libsDir + "libopencv_highgui.a"
               ldLibs += libsDir + "libopencv_imgproc.a"
               ldLibs += libsDir + "libopencv_info.so"
               ldLibs += libsDir + "libopencv_java.so"
               ldLibs += libsDir + "libopencv_legacy.a"
               ldLibs += libsDir + "libopencv_ml.a"
               ldLibs += libsDir + "libopencv_ts.a"
            }
         }
         create("fat") {
         }
     }
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        compile 'com.android.support:appcompat-v7:23.0.0'
        compile project(':openCVLibrary2411')
    }

With this changes I can call my native dummy function in c++ file under jni folder. Also #include <opencv2/core/core.hpp> and others are supported by CLion... When I declare cv::Mat mat; gives me this error:

Linker failed while linking libmymodule.so failed.
C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:278: error: undefined reference to 'cv::fastFree(void*)'
C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:367: error: undefined reference to 'cv::Mat::deallocate()'
collect2.exe: error: ld returned 1 exit status

c++ code:

#include <jni.h>
#include <vector>
#include <string>
#include "helpers.h"
#include <opencv2/core/core.hpp> //This is supported by CLion
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;

extern "C" {
JNIEXPORT jstring JNICALL
Java_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass type) {
    cv::Mat mat; //causing error

    string s = "Cpp v1 - succ ";
    return env->NewStringUTF(s.data());
}

}

Update

- added "z" to ldLibs
- added android.productFlavors block

Now compilation is successfull, application starts for second and then crashes with this messages
Event log:

IllegalArgumentException: Error while starting native debug session: Unable to find process for android.overloaded.nativetestv4 on device huawei-huawei_y530_u00-64a6513ccd8e

Debug info:

Restart ADB integration and try again
Waiting for process: android.overloaded.nativetestv4
DEVICE SHELL COMMAND: run-as android.overloaded.nativetestv4 mkdir -p /data/data/android.overloaded.nativetestv4/lldb/bin
DEVICE SHELL COMMAND: cat /data/local/tmp/lldb-server | run-as android.overloaded.nativetestv4 sh -c 'cat > /data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server; chmod 700 /data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server'
DEVICE SHELL COMMAND: rm /data/local/tmp/lldb-server
DEVICE SHELL COMMAND: cat /data/local/tmp/start_lldb_server.sh | run-as android.overloaded.nativetestv4 sh -c 'cat > /data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh; chmod 700 /data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh'
DEVICE SHELL COMMAND: rm /data/local/tmp/start_lldb_server.sh
Now Launching Native Debug Session
Error while starting native debug session: java.lang.IllegalArgumentException: Unable to find process for android.overloaded.nativetestv4 on device huawei-huawei_y530_u00-64a6513ccd8e

log:

A/libc﹕ Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 3077 (ed.nativetestv4)

解决方案

After few weeks of pain, I succed. Here is my correct code for Android studio 1.3.1, OpenCv 2.4.11. First you should do this OpenCV in Android Studio (don't use paths which contains white space, both for project and opencv extraction folder) then, for opencv to be native:

gradle-wrapper.properties:

distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip 

build.gradle(application):

classpath 'com.android.tools.build:gradle-experimental:0.2.0'

build.gradle(module):

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.0"

        defaultConfig.with {
            applicationId = "android.overloaded.nativetestv4"
            minSdkVersion.apiLevel = 18
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
    }


    android.ndk{
        moduleName = "mymodule"
        ldLibs += ['log']
        cppFlags += "-std=c++11"
        cppFlags += "-fexceptions"
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()



//        ldFlags += linkOpt
        ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]// , "ibopencv_core"
        stl = "gnustl_shared"//"gnustl_static"//"gnustl_shared"//"stlport_static"
    }

    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles += file('proguard-rules.pro')
        }
    }

    android.productFlavors {
        create("arm") {
            ndk.with {
                abiFilters += "armeabi"

                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi\\" //"-L" +

                ldLibs += libsDir + "libnative_camera_r4.3.0.so"
                ldLibs += libsDir + "libopencv_contrib.a"
                ldLibs += libsDir + "libopencv_core.a"
                ldLibs += libsDir + "libopencv_highgui.a"
                ldLibs += libsDir + "libopencv_imgproc.a"
                ldLibs += libsDir + "libopencv_info.so"
                ldLibs += libsDir + "libopencv_java.so"
                ldLibs += libsDir + "libopencv_legacy.a"
                ldLibs += libsDir + "libopencv_ml.a"
                ldLibs += libsDir + "libopencv_ts.a"

            }
        }
        create("armv7") {
            ndk.with {
                abiFilters += "armeabi-v7a"

                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi-v7a\\" //"-L" +

                ldLibs += libsDir + "libnative_camera_r4.3.0.so"
                ldLibs += libsDir + "libopencv_contrib.a"
                ldLibs += libsDir + "libopencv_core.a"
                ldLibs += libsDir + "libopencv_highgui.a"
                ldLibs += libsDir + "libopencv_imgproc.a"
                ldLibs += libsDir + "libopencv_info.so"
                ldLibs += libsDir + "libopencv_java.so"
                ldLibs += libsDir + "libopencv_legacy.a"
                ldLibs += libsDir + "libopencv_ml.a"
                ldLibs += libsDir + "libopencv_ts.a"

            }
        }
        create("x86") {
            ndk.with {
                abiFilters += "x86"
            }
        }
        create("mips") {
            ndk.with {
                abiFilters += "mips"
            }
        }
        create("fat") {

        }
    }

}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:23.0.0'
    compile project(':openCVLibrary2411')
}

.cpp

#include <jni.h>
#include <vector>
#include <string>
#include "helpers.h"
#include <opencv2/core/core.hpp>

using namespace std;

#ifdef __cplusplus
extern "C" {
#endif



JNIEXPORT jstring JNICALL
Java_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass type) {

    cv::Mat mat(33,22, 1);

    string s = "Cpp v1 - succ, rows#:" + Helpers::ToStringNum(mat.rows);
    Helpers::Log(s);

    return env->NewStringUTF(s.data());
}

}

.java

package android.overloaded.nativetestv4;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity
{
    static {
        System.loadLibrary("mymodule");
    }

    public static native String FuncV1();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(this, FuncV1(), Toast.LENGTH_LONG).show();

        ((TextView)findViewById(R.id.txtInfo)).setText(FuncV1());
    }

Update for Android Studio 1.5.1, OpenCV 3.1
1. First you should do this OpenCV in Android Studio (don't use paths which contains white space, both for project and opencv extraction folder), after that you should have normal working Java app
2. Change build.gradle in project root:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle-experimental:0.4.0"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

  1. Change gradle-wrapper.properties:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip

  1. Change build.gradle in opencv module:

    apply plugin: 'com.android.model.library'
    
    model {
        android {
            compileSdkVersion = 23
            buildToolsVersion = "23.0.2"
            defaultConfig.with {
                minSdkVersion.apiLevel = 11
                targetSdkVersion.apiLevel = 23
            }
    
    
        }
    
        android.buildTypes {
            release {
                minifyEnabled = false
                proguardFiles.add(file("proguard-rules.txt"))
            }
        }
    }
    

  2. Change build.gradle in app module:

    apply plugin: 'com.android.model.application'
    
    model {
        android {
            compileSdkVersion = 23
            buildToolsVersion = "23.0.2"
    
            defaultConfig.with {
                applicationId = "android.overloaded.opencv31v1" //Name of package
                minSdkVersion.apiLevel = 11
                targetSdkVersion.apiLevel = 23
                versionCode = 1
                versionName = "1.0"
    
            }
        }
    
        android.ndk {
            moduleName = "native" // Name of C++ module, for System.loadLibrary("native")
            cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality
            cppFlags.add("-fexceptions")
            // YOUR OPENCV DIRECTORY!!!
            cppFlags.add("-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()) 
            ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])
            stl = "gnustl_shared"
        }
    
        android.buildTypes {
            release {
                minifyEnabled = false
                proguardFiles.add(file("proguard-rules.txt"))
            }
        }
    
        android.productFlavors {
            create("arm") {
                ndk.with{
                    abiFilters.add("armeabi")
    
                    File curDir = file('./')
                    curDir = file(curDir.absolutePath)
                    String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi\\"
    
                    ldLibs.add(libsDir + "libopencv_core.a")
                    ldLibs.add(libsDir + "libopencv_highgui.a")
                    ldLibs.add(libsDir + "libopencv_imgproc.a")
                    ldLibs.add(libsDir + "libopencv_java3.so")
                    ldLibs.add(libsDir + "libopencv_ml.a")
    
                }
            }
            create("armv7") {
                ndk.with {
                    abiFilters.add("armeabi-v7a")
    
                    File curDir = file('./')
                    curDir = file(curDir.absolutePath)
                    String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi-v7a\\"
                    ldLibs.add(libsDir + "libopencv_core.a")
                    ldLibs.add(libsDir + "libopencv_highgui.a")
                    ldLibs.add(libsDir + "libopencv_imgproc.a")
                    ldLibs.add(libsDir + "libopencv_java3.so")
                    ldLibs.add(libsDir + "libopencv_ml.a")
                    ldLibs.add(libsDir + "libopencv_ts.a")
    
                }
            }
        }
        android.sources{
            main{
                jni{
                    source{
                        srcDirs += ['src/main/jniMy']
                    }
                }
            }
        }
    }
    dependencies {
        compile fileTree(dir: "libs", include: [$/*.jar/$])
        compile "com.android.support:appcompat-v7:23.1.1" //Do not use 23.2.0 
        compile project(":openCVLibrary310")
    }
    

  3. Create dir app/src/main/jniMy, this is place for yours .cpp files

  4. Optionally create file chelper.c in jniMy, with this code:

    #ifndef OPENCV31V1_CHELPER_H
    #define OPENCV31V1_CHELPER_H
    
    #include <jni.h>
    #include <vector>
    #include <string>
    #include <sstream>
    #include <android/log.h>
    
    using namespace std;
    
    class Helpers{
    public:
        template <typename T>
        static string ToStringNum(T tNumber){
            ostringstream ostrStream;
            ostrStream << tNumber;
            return ostrStream.str();
        }
    
        static void Log(string s){
            __android_log_print(ANDROID_LOG_INFO, "My", s.data());
        }
        static void Log(std::exception ee){
            string s = "Exception: " + string(ee.what()) ;
            __android_log_print(ANDROID_LOG_INFO, "My", s.data());
        }
    
        static long Time(){
            struct timespec now;
            clock_gettime(CLOCK_MONOTONIC, &now);
            return (long)((int64_t)now.tv_sec * 1000LL + now.tv_nsec /1000000LL);
        }
        static string Time(long iTime){
            return ToStringNum(Time() - iTime) + "ms";
        }
    
    };
    #endif //OPENCV31V1_CHELPER_H
    

  5. Create file native_exporter.cpp in jniMy, with this code:

    #include <jni.h>
    #include <string>
    #include <opencv2/core/core.hpp>
    #include "chelper.h"
    
    extern "C"{
    JNIEXPORT jstring     JNICALLJava_android_overloaded_opencv31v1_MainActivity_FuncV1(JNIEnv *env,
    jclass type) {
    
        cv::Mat mat(33,22, CV_32FC2);
    
        string s = "Cpp v1 - succ, rows#:" +Helpers::ToStringNum(mat.rows);
        Helpers::Log(s);
        auto i = 5;
        for (int i2 : {1,3,5}){
            Helpers::Log(Helpers::ToStringNum(i2));
        }
    
        return env->NewStringUTF(s.data());
    }
    }
    

  6. Code in MainActivity.java:

    package android.overloaded.opencv31v1;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.SurfaceView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import org.opencv.android.CameraBridgeViewBase;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    
    public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2
    {
        private static void Log(String sMsg){Log.i("My", "MainActivity." + sMsg );}
    
        static{
            System.loadLibrary("opencv_java3");
            System.loadLibrary("native");
        }
    
        public native String FuncV1();
        JavaCameraViewCustom2 _javaCameraView; //Similar to JavaCameraView
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            if(getSupportActionBar() != null)getSupportActionBar().hide();
            String sRes = FuncV1();
            Toast.makeText(this, sRes, Toast.LENGTH_LONG).show();
    
            ((TextView)findViewById(R.id.txtInfo)).setText(sRes);
    
            _javaCameraView = (JavaCameraViewCustom2)findViewById(R.id.cameraView);
            _javaCameraView.setVisibility(SurfaceView.VISIBLE);
            _javaCameraView.setCvCameraViewListener(this);
    
        }
    
        @Override
        protected void onResume()
        {
            super.onResume();
            _javaCameraView.enableView();
        }
    
        @Override
        protected void onPause()
        {
            super.onPause();
            _javaCameraView.disableView();
        }
    
        Mat _imgBgrTemp;
        @Override
        public void onCameraViewStarted(int width, int height)
        {
            _imgBgrTemp = new Mat(height,width, CvType.CV_8UC4);
        }
    
        @Override
        public void onCameraViewStopped()
        {
            _imgBgrTemp.release();
        }
    
        @Override
        public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame)
        {
            _imgBgrTemp = inputFrame.rgba();
            return _imgBgrTemp;
        }
    }  
    

Android Studio will ask you to change jdk, also it will install new gradle, you should do everything it ask.

这篇关于使用新 gradle 的带有 Android studio 1.3+ 的 OpenCv - 未定义的参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆