之前也曾看过一些介绍 NDK 的文章,但是由于嫌(tuo)麻(yan)烦(zheng)一直没有实践过,这两天读了些文章和文档,打算把 NDK 的项目搭建的一些东西整理一下。

本文主要介绍 Eclipse 下和 Android Studio 下 NDK 开发环境的搭建。

1. NDK 下载

http://developer.android.com/ndk/downloads/index.html

在这里根据平台选择相应的文件下载。

  • Windows 下面可以直接双击下载的 exe 文件解压。

  • Linux 和 OS X 用户需要进入下载的文件目录,执行下面的命令解压。

1
2
chmod a+x android-ndk-r10c-darwin-x86_64.bin
./android-ndk-r10c-darwin-x86_64.bin

2. 环境变量配置

只要把 NDK 目录加入到系统 PATH 变量就好了,这步是为了方便从命令行执行 NDK 脚本。

3. Eclipse 下 NDK 项目搭建

1. 首先在 Eclipse 的设置里选择 NDK 目录。

Android > NDK > NDK Location

2. 新建 Android 项目

3. 添加 native 方法

native 方法在方法签名前加 native 关键字,无方法体。

1
public native String yo();

4. 为项目添加 NDK 支持

在左侧项目视图上点击右键,选择 Android Tools -> Add Native Support…,然后输入 Library Name:libxxx.so,Finish。

之后 Eclipse 会为我们生成 jni 目录以及 Android.mkxxx.cpp 两个文件。

5. 生成 jni 头文件

在 Eclipse 中执行 build 命令,然后进入到项目的 bin\classes 目录,执行 javah -cp 完整类名 android.jar 命令,其中完整的类名是指包含包名,android.jar 是 SDK 目录下对应的 compile SDK 版本目录下面的 android.jar 的路径,比如我的 compile SDK 版本是 23,那我的路径就是 SDK目录\platforms\android-23\android.jar。此时会 javah 会为我们在 classes 目录下生成 jni 头文件。

6. 根据 jni 头文件在 xxx.cpp 中编写 native 代码

此处需要注意的是如果使用 C++ 编写,需要定义 extern "C" 宏。

关于 extern "C" 的详细信息可以参考这篇文章 extern “c”用法解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <jni.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
* Class: me_sxwang_jnipractice_MainActivity
* Method: yo
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_me_sxwang_jnipractice_MainActivity_yo
(JNIEnv *env, jobject thiz) {
return env->NewStringUTF("I come from JNI.");
}

#ifdef __cplusplus
}
#endif

7. 编译 native 代码

进入项目根目录,使用 ndk-build 命令执行编译,编译完成后会在项目的 libs 目录下生成相应的 so 文件。

8. 加载 jni 库,运行调试

在类中添加初始化代码段加载 jni 库

1
2
3
static {
System.loadLibrary("xxx");
}

4. Android Studio 下 NDK 项目搭建(基于 Android Studio 1.5)

1. 新建 Android 项目

2. 在项目的 Project Structure 中选择 NDK 所在目录

3. 为 build.gradle (Module: app) 添加 NDK 模块

在 android > defaultConfig 下新增如下片段,执行 build,会提示需要在 gradle.properties 添加 android.useDeprecatedNdk=true,根据提示添加完后重新 build 一下。

1
2
3
ndk {
moduleName "xxx"
}

https://bintray.com/android/android-tools/com.android.tools.build.gradle-experimental/view 查看 gradle-experimental 插件的最新版,并在 Project 的 buildscript>dependencies classpath 中替换原有的插件。
启用 gralde-experimental 需要修改 module 的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"

defaultConfig.with {
applicationId = "com.google.sample.helloandroidjni"
minSdkVersion.apiLevel = 22
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-android.txt'))
}
}
}

4. 创建 native 方法

同 Eclipse

5. 生成 jni 文件

在 native 方法名上,按 Option + Enter 键根据提示选择第一项 Create function …,Android Studio 会自动为我们生成相应的 c 文件,及方法签名等信息,方便我们编写 native 代码。

6. 编写 native 代码,加载 jni 库,运行调试

同 Eclipse,Android Studio 会自动帮我们编译 native 代码,无需手动编译