第一种适用于创建的项目一开始没有包含C++支持的
1、安装好需要用到的工具:打开SDK Manager,Android SDK ->SDK Tools,选中Cmake、LLDB、NDK,然后点击apply,等待下载完成。
接着打开File -> Project Structure ->SDK Location查看NDK路径是否正确,一般在Android Studio下载ndk,目录一般在sdk安装目录里面的ndk-bundle
这时在项目的local.properties中ndk路径就会自动配置好,如果没有请配置好build下。
为了能够支持C/C++文件,我们还需做一些配置。
首先在工程目录下的gradle.properties文件的末尾加上一句:Android.useDeprecatedNdk=true
然后再在文件build.gradle(Module:app)里面的buildTypes类中添加一个这样的方法
sourceSets {
main {
jni.srcDirs = []
}
}
2、 我们在程序的包下创建一个测试类JNITest,在这个类中添加本地方法。
public static native String getStrFromJNI();
接着打开Terminal(View ->Tool Windows ->Terminal),cd到java下
然后执行javah生成头文件,javah 包名.类名
刷新程序包,就可以看到生成了一个.h头文件
在main目录下创建jni目录,将生成的.h头文件剪切到jni目录,同时在jni目录里面创建.c或.cpp文件,将.h头文件里面的方法复制过来,实现方法体,记得不要忘了导入jni头文件#include <jni.h>
继续往jni目录下添加Android.mk文件,
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := demo
LOCAL_SRC_FILES := demo.c
include $(BUILD_SHARED_LIBRARY)
其中LOCAL_MODULE是生成的so库的名称,LOCAL_SRC_FILES是根据哪个文件生成的。
往jni目录下继续添加Application.mk文件,
APP_ABI := all
APP_PLATFORM := android-14
其中APP_ABI指的是生成对应处理器的so库,这里我们生成所有,APP_PLATFORM是支持最低的安卓版本。
3、 编译so库,前提要配置好ndk-build的环境变量,同样打开Terminal,cd到main目录下,执行ndk-build,等待一会,就会在main目录下生成一个libs目录,里面就是生成的各个处理器对应的so库啦。
4、 使用so库,在JNITest中加入一个静态代码块加载库,下面的demo就是我们在Android.mk下的指定生成的so库名字
static {
System.loadLibrary("demo");
}
在main目录下创建一个jniLibs目录,将libs目录下的文件全部复制到该目录下,就可以正常使用so库了。
第二种适合在创建工程时就添加C++支持的
等待工程创建完,会发现多了cpp目录、External Build Files目录的内容以及CmakeLists.txt文件内容。
cpp 目录
存放所有 native code 的地方,包括源码,头文件,预编译项目等。对于新项目,Android Studio 创建了一个 C++ 模板文件:native-lib.cpp,并且将该文件放到了你的 app 模块的 src/main/cpp/ 目录下。这份模板代码提供了一个简答的 C++ 函数:stringFromJNI(),该函数返回一个字符串:”Hello from C++”
External Build Files 目录
存放 CMake 或 ndk-build 构建脚本的地方。有点类似于 build.gradle 文件告诉 Gradle 如何编译你的APP 一样,CMake 和 ndk-build 也需要一个脚本来告知如何编译你的 native library。对于一个新的项目,Android Studio 创建了一个 CMake脚本:CMakeLists.txt,并且将其放到了你的 module 的根目录下
查看CMakeLists.txt,简单翻译下
# 设置CMake的最低版本构建本机所需库
cmake_minimum_required(VERSION 3.4.1)
# 创建并命名库,将其设置为静态的
# 或共享,并提供其源代码的相对路径。
# 你可以定义多个library库,并使用CMake来构建。
# Gradle会自动将包共享库关联到你的apk程序。
add_library( # 设置库的名称
native-lib
# 将库设置为共享库。
SHARED
# 为源文件提供一个相对路径。
src/main/cpp/native-lib.cpp )
# 搜索指定预先构建的库和存储路径变量。因为CMake包括系统库搜索路径中默认情况下,只需要指定想添加公共NDK库的名称,在CMake验证库之前存在完成构建
find_library( # 设置path变量的名称
log-lib
# 在CMake定位前指定的NDK库名称
log )
# 指定库CMake应该链接到目标库中,可以链接多个库,比如定义库,构建脚本,预先构建的第三方库或者系统库
target_link_libraries( # 指定目标库
native-lib
# 目标库到日志库的链接 包含在NDK
${log-lib} )
创建一个JNITest类,并添加本地方法,在方法那里按Alt+Enter键,提示可以直接创建cpp方法体,可谓是十分方便不需再做其他配置。
如果想添加第三方so库,可以在main目录下创建jniLibs文件,在该目录放入库,然后在build.gradle中Android中添加
sourceSets{
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}