JNI
大约 2 分钟
JNI
目录
参考:
- https://www.bilibili.com/video/BV188411V7Yq(1h快速入门版,选)
- https://www.bilibili.com/video/BV1qW411L7oY(10h详细版)
- JNI最新在线API:https://docs/oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
JNI入门
环境准备
- AndroidStudio环境准备:4.2版本 (2021 04 29 Build),小蜜蜂最新版本可能有问题。JDK 1.8
- 创建NDK工程
- new Peoject > Native C++
- SDK API 16: Android 4.1
- 运行
JNI介绍
如何沟通Java与C/C++
- 上层 Kotlin Java
- 中间件 JNI
- 下层 C/C++
为什么要有JNI?
- 实际使用中,Java需要与本地代码进行交互
JNI与NDK的关系
- 先有JNI才有NDK,JNI是Java的东西,JNI在1996的时候就有了,而NDK是Android的东西,200X左右才有Android
- 那为什么NDK里面有JNI呢?jni.h 的的JDK版本和NDK版本是不一样的:
- NDK版本:D:/Android/Sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/sysroot/usr/include/jni.h (将JDK的JNI再次进行了封装,NDK包括gcc g++ 工具链 JNI 等一堆东西)
- JDK版本:C:/Program Files/Java/jdk1.8.0_131/include/jni.h
常用规则如下:
java类型——属性类型符号
- boolean, Z
- byte, B
- char, C
- short, S
- int, I
- long, J
- float, F
- double, D
- void, V
- object, L完整类名
- array[数组的数据类型,
int [] […………
- mehtod(参数类型)返回直类型,
void name (int a, double b) (ID) V
实战
< MainActivity.java
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
private ActivityMainBinding binding;
private String name = "Derry";
public native String stringFromJNI(); // (原生函数,cpp进行实现)
public native void changeName(); // (原生函数,cpp进行实现) 改变我们的属性name
@Override
protected void onCreate(Bundle saveInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
serContentView(binding.getRoot());
TextView tv = binding.sampleText;
tv.serText(stringFromJNI());
System.out.prinln("name修改前是:"+name);
changName();
System.out.prinln("name修改后是:"+name);
}
}
< native-lib.cpp
#include <jni.h>
#incldue <string>
extern "C" JNIEXPORT jstring JNICALL
MainActivity.stringFromJIN(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from Cpp";
return env->NewStringUTF(hello.c_str());
}
/**
* @param env JNI环境,核心,桥梁
*/
extern "C" // 下面的代码,重用C的编译方式。为什么要这样,后面专门讲JNIEnv源码
JNIEXPORT void JNICALL
Java_com_derry_as_1jni_1project_MainActivity_changeName(JNIEnv* env, jobject this) {
}
jni.h 源码
< jni.h
// < 139 line
// 无论Cpp还是C,都是要访问 JNINativeInterface 这个C结构体的
#if defined(__cplusplus) // C++
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else // C
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNINativeInterface* JavaVM;
#endif
// < 490 line
struct _JNIEnv {
const struct JNINativeInterface* functions; // 这里又是个结构体,见下
...
}
// < 150 line
// 核心,只要将里面的300多个函数学完,就基本会了
struct JNINativeInterface {
...
}