Zane'Blog

JNI和NDK编程-NDK的开发流程

我准备迎接一段美好的时光 沿着海岸 脚踩着沙滩

NDK的开发流程是基于JNI的,其主要由如下几个步骤。

下载NDK

官网下载

云盘下载 (密码:f8h5)

配置NDK

设置NDK路径

选择File > Project Structure > SDK Location > Android NDK location,指定NDK的路径。

这里写图片描述

这里写图片描述

也可以通过直接修改local.properties文件,在里面指定NDK的所在目录:

ndk.dir=D\:\Development_Tools\AndroidStudio\android-ndk-r14b

这里写图片描述

设置完环境变量后,ndk-build命令就可以使用了,通过ndk-build命令就可以编译产生so库。

Windows环境下的开发

方式一:

1、在 jni 目录下创建 Android.mk 文件,编写内容:

1
2
3
4
5
6
7
8
9
10
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 要生成的.so库名称;java代码 System.loadLibrary("jni-test"); 加载的就是它。
LOCAL_MODULE := jni-test
# C文件
LOCAL_SRC_FILES := test.c
include $(BUILD_SHARED_LIBRARY)

2、在 jni 目录下创建 Application.mk 文件,编写内容:

1
2
3
4
#目前支持:
APP_ABI := armeabi armeabi-v7a x86
#APP_ABI := armeabi armeabi-v7a x86 mips arm64-v8a mips64 x86_64

这里对Android.mk和Application.mk做一下简单的介绍。在Android.mk中,LOCAL_MODULE表示模块的名称,LOCAL_SRC_FILES表示需要参与编译的源文件。Application.mk中常用的配置项是APP_ABI,它表示CPU的架构平台的类型,目前市面上常见的架构平台有armeabi、x86和mips,其中在移动设备中占据主要地位的是armeabi,这也是大部分apk中只包含armeabi类型的so库的原因。默认情况下NDK会编译产生各个CPU平台的so库,通过APP_ABI选项即可指定so库的CPU平台的类型,比如armeabi,这样NDK就只会编译armeabi平台下的so库了,而all则表示编译所有CPU平台的so库。

3、在Terminal中使用 cd 命令跳转到 jni 目录下,使用 ndk-build 命令编译C/C++文件生成.so文件。

这里写图片描述

生成的资源,如图所示:

这里写图片描述

4、引入.so文件,调试、运行

首先,要注意ndk-build命令生成的.so文件默认在src/main/libs目录下,此目录非Android Studio 默认的.so库目录,直接调试/运行会报错。要么在src/main下创建jniLibs文件夹,将.so文件全部移动到src/main/jniLibs中去,jniLibs为默认目录。要么修改app目录下的build.gralde,在android节点下添加sourceSets部分,设置jni库的资源路径:

1
2
3
4
5
6
7
8
9
10
android {
...
sourceSets.main {
jniLibs.srcDirs = ['src/main/libs']//默认为jniLibs
}
...
}

然后,运行起来看效果

这里写图片描述

注意:如果使用方式一,那么每当修改了c/c++文件之后,都需要通过ndk-build命令,重新编译成.so文件。

方式二:

1、修改build.gradle配置,在defaultConfig里面新增一下代码:

1
2
3
4
5
6
7
8
9
defaultConfig {
...
ndk{
moduleName "jni-test" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //生成CPU平台下的so库
}
}

2、选择 build -> Rebuild Project,生成.so文件

这里写图片描述

3、代码已经编写完成,运行程序看看效果

这里写图片描述

常见问题

1、编译错误Error: Your project contains C++ files but it is not using a supported native build system.

这里写图片描述

解决方法:

在gradle.properties里面新增:

android.useDeprecatedNdk=true

坚持原创技术分享,您的支持将鼓励我继续创作!