一 概念
NDK (Native Development Kit),
NDK是Google开发的一套开发和编译工具集,可以生成动态链接库
1.1 NDK与JNI的关系
JNI (Java Native Interface), java 本地化接口,可以通过JNI调用系统提供的API、操作系统(不管什么系统底层都是使用C/C++作为驱动的),Java在在运行时需要编译成虚拟机可以运行的class字节码,然后在由虚拟机编译成机器码,而C/C++可以直接编译成机器码,所以效率上Java不如C/C++,JNI测试Java和C/C++互调之间的桥梁
所以在Android开发中使用NDK 需要编写c/c++代码,而C/C++和Java的沟通桥梁是JNI,那可以说是NDK就是Android用于JNI开发的工具
1.2 手动创建JNI项目,生成SO文件
Android studio是支持创建JNI项目的,这样省略了一些手动配置的麻烦,当然我们也需要知道在除了AS之外开发是怎么去做的,也就是创建一个JNI项目的步骤是什么?
- 在普通项目中首先创建一个包含native方法的Java类
public class JNIUtils {
public native int firstJniMethod(int first);
}
- 进到该文件目录下,使用javah命令生成native的头文件(Mac电脑Javah 可用javac XXX.java -h . 命令代替),同目录生成.h文件
包名_类明.h
- main文件下创建jni 文件夹,将生成的头文件拷贝到此,并创建.c文件,实现刚才生成的文件中的方法
#include <com_kpa_myapplication_JNIUtils.h>
JNIEXPORT jint JNICALL Java_com_kpa_myapplication_JNIUtils_firstJniMethod(JNIEnv* env, jobject obj, jint first){
jint res = 10;
return res;
}
- 在JNI文件下创建Android.mk 和Application.mk
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := 名称
LOCAL_SRC_FILES := Test.c
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := all
- 调用so库
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
}
}
// java
new JNIUtils().firstJniMethod(1)
在开发中我们其实不需要手动的去配置JNI的项目,一般开发时直接使用AS创建项目就可以了
1.3 AS开发NDK
AS 3.6.1 使用方法
1.新建项目
2. 选择native C++ 模版
3. 选择C++ support (一般选择默认,也可以指定版本)
4. 运行项目
二、 目录解析
2.1 目录
与传统项目区别,在main文件下多了一个cpp文件夹,这个文件下存放着开发的文件,是C++文件
extern "C" JNIEXPORT jstring JNICALL
Java_com_kpa_jnijavademo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject obj/* this */) {
return env->NewStringUTF(hello.c_str());
}
开发时只需要以该文件为基础
2.2 第一个函数解析
Java_com_kpa_jnijavademo_MainActivity_stringFromJNI 对应的Java中的类的全目录+ 方法名称
Java 中
所属类为MainActivity
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
Java_表示Java文件,
JNIEnv: 类型实际上是可以代表在native中的Java环境,操作Java代码的方法都在里面,
jobject obj
native 不是static 方法, obj就表示native方法的所属类的实例
native 是static obj表示native方法的类的class对象实例