android studio自从1.3以后开始对android的ndk进行支持了,所以现在基本android开发可以废弃eclipse了,毕竟跟着官方的趋势走肯定不会错的。对于开发环境搭建这种事永远都是开始难后面,只要参照一个正确的教程就能事半功倍,对于opencv的在android的搭建教程官网还是停留在eclipse上面,现在我还没在官网找到关于如何在android studio上的官方教程,官方给的实例也是eclipse上面的。其实,移过来也并不麻烦。
为了开发方便,强烈建议将环境变量配置好,我的系统是OS X,我觉得做android开发最好不要在win平台上进行开发,配置之类太麻烦。像我的环境变量配置的话一般在.bashrc中alias起别名搞定,我觉得这样配置环境变量比较清楚。当然也可以定义PATH。
关于opencv for android,下载下来以后可以看到里面的sdk目录下面有java和native两个文件夹,说明opencv的使用方式有两种,java代码调用和native方法调用,两种的运行效率差不多的,就是看你个人熟悉哪种语言了,个人觉得可能对于一些移植项目来说用native比较方便一些,对于比较熟悉java的开发人员来说就用java代码好了。
另外,还有sample中可以看到的是官方提供的基于eclipse的实例项目代码。
项目主要分为两个模块,一个是你新建的自己的模块,一个是opencv的项目模块,opencv的项目模块是作为你自己的项目模块的一个依赖,opencv的模块就是把你下载的opencv-android中的java整个复制进来,新建一个gradle构建脚本,注意版本要和app中的一致。当然如果你不需要用java开发opencv的话也可以不复制过来而只使用native代码开发也可以。这里为了方便所以将java代码复制进来了。
在app模块中新建一个jni目录,这里存放你的cpp代码和Android.mk文件,具体也不详述,想回顾一下可以看android NDK入门
再新建一个jniLibs目录,用来存放cpp进行build完成以后的so文件,另外,需要将opencv中相应的libopencv-java3.so拷贝进来。在程序静态代码块中加载这个so文件和自己定义的so。
include ':app', ':library'
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "zalezone.imagemagic"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
// begin
sourceSets.main {
jni.srcDirs = [] //disable automatic ndk-build call
}
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
commandLine "/Users/zale/Library/Android/sdk/ndk-bundle/ndk-build",
'NDK_PROJECT_PATH=build/intermediates/ndk',
'NDK_LIBS_OUT=src/main/jniLibs',
'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
'NDK_APPLICATION_MK=src/main/jni/Application.mk'
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile project(':opencv3-java')
compile 'com.android.support:appcompat-v7:23.1.1'
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
注意,里面的sdk version需要一样,不然编译不会通过的。其中的gradle脚本中将默认的jni目录置为空了,然后在脚本中对cpp文件进行编译
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#opencv
OPENCVROOT:= /Users/zale/MyFileRoot/software_source/OpenCV-android-sdk
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk
LOCAL_SRC_FILES := zalezone_imagemagic_opencv_grayprocess_ImageProc.cpp
LOCAL_LDLIBS += -llog
LOCAL_MODULE := ProcLib
include $(BUILD_SHARED_LIBRARY)
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-16
运行gradle脚本,正常情况下会发现自动生成了一个自己所定义的一个so文件,这就是我嘛在java代码中所需要加载的so库。像平常的灰度处理就可以通过cpp写,通过传入图片的矩阵数据进行native方法的灰度处理以后再返回给java代码进行显示。
如果项目出现了编译错误,根据出错信息好好分析一下,搜索一下一般都能解决问题,祝好运!
对于native代码头文件的自动生成方法,以前都是通过命令行到达相应的文件目录下面以后手动进行javah 然后生成我们所需要的头文件,这样的操作比较麻烦,现在我们可以借助android studio提供的工具来方便的完成,进入Tools->External tools,自己新建一个tool,用来为外部命令javah进行配置,这样我们如果要生成本地代码的头文件的话只要通过自己新建的tool来快速生成,具体配置如下图所示
关于android studio中的NDK配置的话还有另一种方法,现在用的比较多的都是我上面所介绍的配置方式,但是gradle还有一个试验性的版本,这个版本对于gradle的语法也有了较大的更改,对于NDK的配置也融合进了gradle脚本,所以就无需Android.mk文件了,但是毕竟这个还是试验性版本,具体大规模应用应该还有一段时间,所以也不去深究了,现在还是用原来的方式比较好。