简介
最近在研究Flutter Engine,里面涉及到JNI的知识,笔记记录一下关于JNI类型签名和方法签名。
数据类型
基本数据类型
| Java数据类型 | JNI本地类型 | C/C++数据类型 | 描述说明 |
|---|---|---|---|
| boolean | jboolean | unsigned char | C/C++无符号8为整数 |
| byte | jbyte | signed char | C/C++有符号8为整数 |
| char | jchar | unsigned short | C/C++无符号16位整数 |
| short | jshort | signed short | C/C++有符号16位整数 |
| int | jint | signed int | C/C++有符号32位整数 |
| long | jlong | signed long | C/C++有符号64位整数 |
| float | jfloat | float | C/C++32位浮点数 |
| double | jdouble | double | C/C++64位浮点数 |
引用数据类型
| Java引用类型 | JNI引用类型 | 描述说明 |
|---|---|---|
| java.lang.Object | jboject | 可以表示任何Java的对象,或者没有JNI对应类型的Java对象(实例方法的强制参数) |
| java.lang.String | jstring | Java的String字符串类型的对象 |
| java.lang.Class | jclass | Java的Class类型对象(静态方法的强制参数) |
| Object[] | jobjectArray | Java任何对象的数组表示形式 |
| boolean[] | jbooleanArray | Java基本类型boolean的数组表示形式 |
| byte[] | jbyteArray | Java基本类型byte的数组表示形式 |
| char[] | jcharArray | Java基本类型char的数组表示形式 |
| short[] | jshortArray | Java基本类型short的数组表示形式 |
| int[] | jintArray | Java基本类型int的数组表示形式 |
| long[] | jlongArray | Java基本类型long的数组表示形式 |
| float[] | jfloatArray | Java基本类型float的数组表示形式 |
| double[] | jdoubleArray | Java基本类型double的数组表示形式 |
| java.lang.Throwable | jthrowable | Java的Throwable类型,表示异常的所有类型和子类 |
| void | void | N/A |
数据类型描述符
数据类型描述符解释
在JVM虚拟机中,存储数据类型的名称时,是使用指定的描述符来存储,而不是我们习惯的 int,float 等
数据类型描述符对照表
| Java类型 | 描述符类型 |
|---|---|
| int | I |
| long | J |
| byte | B |
| short | S |
| char | C |
| float | F |
| double | D |
| boolean | Z |
| void | V |
| 引用类型 | L+类全名+; |
| 数组 | [ |
| 方法 | (参数)返回值 |
示例
flutter注册代码
bool FlutterMain::Register(JNIEnv* env) {
static const JNINativeMethod methods[] = {
{
.name = "nativeInit",
.signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
"lang/String;Ljava/lang/String;Ljava/lang/String;J)V",
.fnPtr = reinterpret_cast<void*>(&Init),
},
{
.name = "nativePrefetchDefaultFontManager",
.signature = "()V",
.fnPtr = reinterpret_cast<void*>(&PrefetchDefaultFontManager),
},
};
jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
if (clazz == nullptr) {
return false;
}
return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
}
}
还原nativeInit在java中的方法声明
"(Landroid/content/Context;[Ljava/lang/String;
Ljava/lang/String;
Ljava/lang/String;
Ljava/lang/String;
J)V"
public void nativeInit(Context context,
String[] args,
String s1,
String s2,
String s3,
long l);
实际情况
private static native void nativeInit(
@NonNull Context context,
@NonNull String[] args,
@Nullable String bundlePath,
@NonNull String appStoragePath,
@NonNull String engineCachesPath,
long initTimeMillis);