从Android Studio1.3以后,在Android 环境开发JNI程序搭建开发环境变得相对简单。这里就来介绍一下基于Android Studio如何进行jni开发。在介绍之前,先跟大家说一下JNI和NDK都是什么,方便大家理解。
JNI是java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以 调用java代码。JNI 是本地编程接口,Java和C/C++互相通过的接口。Java通过C/C++使用本地的代码的一个关键性原因在于C/C++代码的高效性。
NDK是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这 些工具对开发者的帮助是巨大的。它集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪 些文件需要编译”、“编译特性要求”等),就可以创建出so。它可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
然后跟大家说一下环境的搭建
这里也可以去修改工程下的local.properties
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Mar 03 11:29:37 CST 2016
ndk.dir=C\:\\software\\sdk\\ndk-bundle
sdk.dir=C\:\\software\\sdk
设置好NDK之后,开始设置gradle,设置gradle主要需要设置三个地方,设置好之后就可以直接编写和编译JNI代码了,不需要像以前一样编写Makefile,相当方便。但是设置gradle也是需要比较小心的,由于当前NDK还处于Experimental 阶段,更新不断,经常会爆出各种奇怪的错误,因此也要特别留心。好了废话不多说,下面来介绍设置gradle的三个主要步骤。
首先设置TopLevel gradle,也就是Project gradle,这里比较简单。
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
// classpath 'com.android.tools.build:gradle:1.5.0'
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
}
还要多提一句的是,这里设置的是gradle-experimental:0.4.0,后面对应设置gradle wrapper的时候要对应gradle2.8-all 版本,这里先说到这里。
#Wed Oct 21 11:34:03 PDT 2015
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
接着设置 Module gradle,这一步是比较麻烦的。由于我们在创建工程的时候自动生成的这个gradle文件内容比较多,而且如果要使用NDK的话这个gradle变化比较大,这里直接贴出需要使用NDK的gradle,然后来进行说明。
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.oracleen.rl.easyar"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "HelloARVideoNative"
cppFlags.add("-I${file("../../package/include")}".toString())
cppFlags.add("-DANDROID")
cppFlags.add("-fexceptions")
cppFlags.add("-frtti")
stl = "gnustl_static"
ldLibs.add("log")
ldLibs.add("GLESv2")
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-rules.pro"))
}
}
android.productFlavors {
create("arm") {
ndk.with {
abiFilters.add("armeabi-v7a")
}
}
}
android.sources {
main {
jni {
dependencies {
library file("../../package/Android/libs/armeabi-v7a/libEasyAR.so") abi "armeabi-v7a"
}
}
}
}
}
dependencies {
// compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.1'
compile fileTree(dir: '../../package/Android/libs', include: ['*.jar'])
}
和自动生成的gradle相比,首先是 apply plugin: ‘com.android.application’ 变成了 apply plugin: ‘com.android.model.application’。下面的配置也需要包装在model{}中。
这个gradle的配置有几点需要注意的:
NDK开发主要有两中情况:一种是使用已经编译好的.so动态库;一种是使用c/c++源代码开发。我会分别介绍。
这里我们起一个名字是“HelloARVideoNative”的JNI库,androidstudio会把我们编写的c/c++代码编译成这个名字的.so文件。
android.ndk {
moduleName = "HelloARVideoNative"
stl = "gnustl_static"
ldLibs.add("log")
ldLibs.add("GLESv2")
}
然后我们在我们需要使用c/c++方法的类中引用库,并且声明本地接口。
然后就可以去c/c++文件中去实现我们的方法了。
在app下的gradle中做如下配置
android.sources {
main {
jni {
dependencies {
library file("../../package/Android/libs/armeabi-v7a/libEasyAR.so") abi "armeabi-v7a"
}
}
}
}
指向我们的so库文件位置,然后在需要引用的地方
static {
System.loadLibrary("EasyAR")
}
然后我们就可以使用so库中的方法了。
最后,附上相关的资源.其实在android的官网已经提供了很完善的教程了.还有github上也托管了sample代码.
Experimental Plugin User Guide: http://tools.android.com/tech-docs/new-build-system/gradle-experimental
github sample: https://github.com/googlesamples/android-ndk
官方ndk视频教程: https://youtu.be/okLKfxfbz40 (需要)