在 Android Studio 中利用 gradle 来自动编译 jni

在最近的 Android 开发中,项目逐渐从 Eclipse 迁移到 Android Studio 中来,google 官方现在并未在 Android Studio 中支持 ndk 的开发,但是我们可以利用 gradle 自动编译 jni。

步骤

1. 在新建项目中找到 local.properties,在里面加入 ndk 的路径 (ndk 必须是 r9 以上):

1
ndk.dir=E\:\\Android\\ndk-r10d

2. 在 app\src\main 中新建 jni 文件夹,在这里面存放要编译的 c/c++ 文件以及 Android.mk

3. 在 app 中的 build.gradle 中加入两个 task:ndkBuild 和 copyJniLibs,第一个 task 为 ndk 执行编译,第二个 task 将编译好的 so 库 copy 至 jniLibs 目录,这样才 Android Studio 最后打包的时候才会将 so 库打包进去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.xxx.yyy"
versionCode 1
versionName '1.0'
minSdkVersion 10
targetSdkVersion 21
}

buildTypes {
release {
minifyEnabled false
proguardFiles ('proguard-android.txt')
}
}

tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn 'ndkBuild', 'copyJniLibs'
}

sourceSets {
main {
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}

task ndkBuild(type: Exec) {
def ndkDir = project.plugins.findPlugin('com.android.application').sdkHandler.getNdkFolder()
commandLine "$ndkDir/ndk-build.cmd", '-C', 'src/main/jni',
"NDK_OUT=$buildDir/ndk/obj",
"NDK_APP_DST_DIR=$buildDir/ndk/libs/\$(TARGET_ARCH_ABI)"
}

task copyJniLibs(type: Copy) {
from fileTree(dir: file(buildDir.absolutePath + '/ndk/libs'), include: '**/*.so')
into file('src/main/jniLibs')
}

这两个 task 不要放在 android {} 中,放在 android {} 外即可,否则无法编译。其中 NDK_APP_DST_DIR 为编译后的库存放的文件夹,根据需求自己设定,我在这里是设置为的 buildDir 下的 nkd 文件夹

4. 最后编译,Android Studo 会自动执行 ndkBuild 和 copyJniLibs 这两个 task

ps: 也可以使用命令行的方式来执行这两个 task

$ gradle ndkBuild copyJniLibs

使用这个命令前,请先找到 gradle 的目录下 bin 目录,并添加到环境变量中去