操作系統(tǒng):MAC OS X 10.11.5
Android Studio 版本:2.1.2
OpenCV for Android 版本:2.4.9
Android NDK 版本:r11c
其實(shí)呢,這個(gè)過(guò)程不是很復(fù)雜搔体,大概需要做以下那么幾件事情
- 下載并配置好OpenCV for Android 睁本、Eigen和NDK
- 寫(xiě)好cpp程序,Android.mk隙咸,Application.mk以及Java程序
- 對(duì)cpp程序用
ndk-build
編譯成動(dòng)態(tài)庫(kù)或者在運(yùn)行的時(shí)候進(jìn)行編譯怖亭,然后運(yùn)行Java程序的時(shí)候調(diào)用動(dòng)態(tài)庫(kù)
接下來(lái)我們一個(gè)一個(gè)的來(lái)過(guò)一下及穗,看看具體應(yīng)該怎么做
下載及配置
-
NDK
下載地址:NDK- 在Android Studio 中添加NDK,F(xiàn)ile -> Project Structure -> SDK Location 最下面一欄添加ndk的路徑
- 在app/src/main下面添加文件夾jni哄褒,主要用于存放C++文件及其頭文件
然后需要在gradle.properties
里面加一行android.useDeprecatedNdk=true
-
OpenCV for Android
下載地址:OpenCV for Android- 下載完成之后稀蟋,Android Studio -> File -> import mudules,選擇OpenCV文件夾下的sdk/java
- 新導(dǎo)入的openCVLibrary249(300表示3.0.0,其它版本類(lèi)推)呐赡,下面有個(gè)build.gradle文件退客,將里面的compileSdkVersion、buildToolsVersion链嘀、minSdkVersion萌狂、targetSdkVersion修改,使其與app目錄下的build.gradle保持一致管闷。
Eigen
下載地址:Eigen
下載解壓之后粥脚,直接將里面Eigen文件夾整個(gè)拷貝到j(luò)ni下
程序的編寫(xiě)
- cpp程序
我只想簡(jiǎn)單試試能不能調(diào)用opencv以及eigen,所以cpp程序很簡(jiǎn)單包个,只是把Eigen及opencv.hpp調(diào)用一下刷允,沒(méi)報(bào)錯(cuò)的話(huà)應(yīng)該就沒(méi)問(wèn)題冤留,之后再寫(xiě)個(gè)小程序
注意這里面的函數(shù)名字結(jié)構(gòu)是Java_包名Activity名函數(shù)名,這個(gè)你需要修改成你的
#include <iostream>
#include <Eigen/Dense>
#include <math.h>
#include <jni.h>
#include <opencv2/opencv.hpp>
extern "C"{
JNIEXPORT int JNICALL Java_com_example_gaoxiangzhang_datacollection_MainActivity_test (JNIEnv *env, jobject obj, int x)
{
return x;
}
}
Android.mk以及Application.mk的使用方法大家可以看看這里
- Android.mk
This page describes the syntax of the Android.mk build file, which glues your C and C++ source files to the Android NDK.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=STATIC
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include /path-to-opencv/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)
- Application.mk
This document explains the Application.mk build file, which describes the native modules that your app requires. A module can be a static library, a shared library, or an executable.
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
- Java 程序
在Java程序中定義一個(gè)接口树灶,并且載入生成的動(dòng)態(tài)庫(kù)纤怒,然后在程序中調(diào)用這個(gè)接口就可以了
public static native int test(int x);
static {
System.loadLibrary("test");
}
編譯cpp程序
有兩個(gè)方法,一個(gè)是在build.gradle
寫(xiě)好怎么編譯天通,一個(gè)是先編譯好泊窘,我選擇的是先編譯好。
在終端下首先cd到j(luò)ni目錄像寒,然后運(yùn)行ndk中的ndk-build程序即可
path-to-project/app/src/main/jni $ path-to-ndk/android-ndk-r11c/ndk-build
編譯好后呢烘豹,你會(huì)發(fā)現(xiàn)app/src/main下面多了一個(gè)libs的文件夾,里面就有我們需要的動(dòng)態(tài)庫(kù)诺祸,我們就可以調(diào)用啦
還有最后一步要做的就是在app的build.gradle加上
sourceSets.main{
jniLibs.srcDir 'src/main/libs' //set .so files directory to libs
jni.srcDirs = [] //disable automatic ndk-build call
}
防止你們加錯(cuò)携悯,在加點(diǎn)代碼…
android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
applicationId "com.example.gaoxiangzhang.datacollection"
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets.main{
jniLibs.srcDir 'src/main/libs' //set .so files directory to libs
jni.srcDirs = [] //disable automatic ndk-build call
}
}
告訴程序動(dòng)態(tài)庫(kù)在哪里以及不需要調(diào)用ndk-build再編譯了,因?yàn)槲覀円呀?jīng)編譯過(guò)了
main文件夾里面的目錄是這個(gè)樣子的
當(dāng)然這中間可能會(huì)遇到一些問(wèn)題筷笨,你可以選擇google或者提問(wèn)憔鬼,我之前忘了記錄了,不過(guò)其實(shí)錯(cuò)誤提醒都比較明顯胃夏,大家遇到錯(cuò)誤不要只想著直接搜索答案轴或,無(wú)腦解決…應(yīng)該自己先分析一下,嗯嗯其實(shí)我是在說(shuō)我自己仰禀。