前言
结束了第一阶段 C++ 基础,接下来开始 JNI 基础的学习,经过对 JNI 学习资料的筛选,最后选中了
南洋理工大学 JNI 教程,课程内容全英文的,刚好拿来锻炼一下阅读能力
由于 Java 基于虚拟机运行,有跨平台的优点,而原生代码没有这一特性,所以我们要根据手机 cpu 类型来制作对应的库文件,Android 端常见的平台类型有 arm64-v8a,armeabi,armeabi-v7a,mips,mips64,x86,x86_64
相关链接
调用 native 代码
在 JNI 代码中我们经常看到 System.loadLibrary 语句,这句话的含义是 Java 代码调用动态链接库,其实内部进行了方法指针强制转换等一系列操作,因为 Android 基于 Linux 内核,loadLibrary 内部封装的就是 Linux 平台加载 so 动态库文件的代码,网上有大神对 loadLibrary 源代码进行了分析.
JNI 的开发流程
- 使用 Java 编写声明 Native 方法的类
- 将 Class 文件编译成字节码
- 使用 javah -jni 指令生成 .h 头文件
- 使用 C/C++ 代码实现定义的方法
- 生成 so 动态库文件(windows 平台生成 dll,linux/unix 生成 so,macOs 生成 jniLib)
- Java 代码使用 so 动态库
Hello,Word 程序
NDK 的环境配置在网上一搜一大把,需要下载 LLDS,NDk 和 Cmake 工具,我们再这里就不做详细说明了.
- 定义 native 方法
首先创建 java 文件,定义原生代码的方法名以及返回值
/**
* @author : kai.mao
* @date : 2019/8/5
*/
public class JniUtil {
// 定义 native 方法
public native String sayHelloWorld();
// 加载 so 动态库文件
static {
System.loadLibrary("HelloWord");
}
}
- 使用 javah 指令生成 .h 头文件
在 Terminal 中首先 cd 到该 java 所在的文件夹,然后使用 javah
// 需要相对路径
D:\TopAndroid\HelloJNI\app\src\main\java>javah com.bailun.kai.hellojni.JniUtil
生成如下文件,并将该文件放到 main/cpp 文件夹中
image.png- 根据头文件编写 cpp 文件
在 cpp 下新建 xxx.cpp 文件,代码如下:
//
// Created by Admin on 2019/8/5.
//
#include "com_bailun_kai_hellojni_JniUtil.h"
JNIEXPORT jstring JNICALL Java_com_bailun_kai_hellojni_JniUtil_sayHelloWorld
(JNIEnv *env, jobject){
return env->NewStringUTF("Hello,World!");
}
- 创建 CMakeLists.txt 文件
cmake_minimum_required(VERSION 3.4.1)
add_library( # Specifies the name of the library.
# 这里是你so的名字。
HelloWord
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
#这里是刚才 创建的c++ 代码的名字
src/main/cpp/HelloWorld.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
# 这里是你so的名字。
HelloWord
# Links the target library to the log library
# included in the NDK.
${log-lib} )
- 生成 so 文件
使用 As Build 项目后,可在 cmake 目录下看到生成的 so
文件
网友评论