第一天
1、为什么要学习JNI
本人之前是做flutter开发的。在flutter开发中免不了与android和ios底层接触,于是后面后学习了部分andorid和ios。在android第三方插件的接入时发现有很多插件内是有jni库的调用的。想要深入学习android打开jni的学习必不可少。于是开始研究jni的开发。
2、学习的准备工作
安装java环境 eclipse ,visual studio(2019)eclipse用于创建java项目 vs2019用于创建jni dll 特别说明,单纯开发android的jni so库是用不到下载这么多软件的。一个android studio全部搞定,不仅开发效率高,还有很强的代码补全功能。但是为了学的更深入我从开发jni 的dll开始。
java开发环境安装自行百度,需要配置环境变量方便后面直接在控制台进行java命令。
3、简单的尝试,实现java调用jni的native方法获取一个字符串
1. 创建java项目
2. 创建一个package,包名不要带'_'
3. 在包下面建立一个class 取名Study1(随便) 并创建一个native方法 public native String getSign();
4. 控制台进如src项目src目录 并执行java指令生成.h头文件
5. 用VS创建一个C++控制台项目(NdkJni)把NdkJni.cpp改成.c文件。然后把com_sohubill_ndkstudy_Study1.h文件复进这个项目文件夹下面,并且在项目的头文件内添加。此时会有下面错误
6. 把jni.h和jni_md.h文件复制紧VS项目内。这两个文件在JAVA环境文件夹的include和include\win32内。并且com_sohubill_ndkstudy_Study1.h内的#include <jni.h>改成#include "jni.h"引号是引入本地头文件,<>是引入配置的系统头文件
7.vs中选择调试-》NdkJin调试属性-》常规-》配置类型-》动态库dll 8. 选择生成-》配置管理器-》选择合适自己的活动解决方案平台,这边再windows下面所以选择X64 下面是头文件内容
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_sohubill_ndkstudy_Study1 */
#ifndef _Included_com_sohubill_ndkstudy_Study1
#define _Included_com_sohubill_ndkstudy_Study1
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_sohubill_ndkstudy_Study1
* Method: getSign
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_sohubill_ndkstudy_Study1_getSign
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
下面是NdkJni.c文件的内容
#include "com_sohubill_ndkstudy_Study1.h"
JNIEXPORT jstring JNICALL Java_com_sohubill_ndkstudy_Study1_getSign
(JNIEnv* env, jobject jobj) {
return (*env)->NewStringUTF(env, "12345678");
}
生成解决方案 9. 在java项目中添加dll的加载整体代码如下。执行
package com.sohubill.ndkstudy;
public class Study1 {
static {
System.load("G:\\NDKProjcet\\NdkJni\\x64\\Debug\\NdkJni.dll");
}
public static void main(String[] args) {
Study1 study=new Study1();
String sign = study.getSign();
System.out.println(sign);
}
public native String getSign();
}
输出结果为12345678
特别注意:mac下vs studio无法执行c生成动态库,用vs code 编写代码,并用命令行 gcc -dynamiclib -I /Library/Java/JavaVirtualMachines 类名.c -o 动态库名.jnilib 来生成动态库