要了解JNINativeMethod,我们首先得学会看懂标杆代码,而最好的标杆代码肯定为android原始代码,我们可以依据android的原始代码去学习JNINativeMethod。
以下为WiFi部分JNINativeMethod
[frameworks\base\core\jni\android_net_wifi_Wifi.cpp]
/*
* JNI registration.
*/
static JNINativeMethod gWifiMethods[] = {
/* name, signature, funcPtr */
{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
{ "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
{ "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
{ "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant },
{ "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
{ "p2pEnabled", "(I)Z", (void*) android_net_p2pEnabled },
{ "connectToSupplicant", "(Ljava/lang/String;)Z",
(void *)android_net_wifi_connectToSupplicant },
{ "closeSupplicantConnection", "(Ljava/lang/String;)V",
(void *)android_net_wifi_closeSupplicantConnection },
{ "waitForEvent", "(Ljava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_waitForEvent },
{ "doBooleanCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
(void*) android_net_wifi_doBooleanCommand },
{ "doIntCommand", "(Ljava/lang/String;Ljava/lang/String;)I",
(void*) android_net_wifi_doIntCommand },
{ "doStringCommand", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_doStringCommand },
};
蓝色代码部分解释:上面蓝色部分为自己添加的一个私有方法,第二个变量(I)Z 是因为:I是因为java方法带int类型的参数,Z 代表返回boolean类型值
Andoird 中使用了一种不同传统Java JNI的方式来定义其native的函数。其中很重要的区别是Andorid使用了一种Java 和 C 函数的映射表数组,并在其中描述了函数的参数和返回值。这个数组的类型是JNINativeMethod,定义如下:
typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod;
第一个变量name是Java中函数的名字。
第二个变量signature,用字符串是描述了函数的参数和返回值
第三个变量fnPtr是函数指针,指向C函数。
其中比较难以理解的是第二个参数,例如
"()V"
"(II)V"
"(Ljava/lang/String;Ljava/lang/String;)V"
实际上这些字符是与函数的参数类型一一对应的。
"()" 中的字符表示参数,后面的则代表返回值。例如"()V" 就表示void Func();
"(II)V" 表示 void Func(int, int);
具体的每一个字符的对应关系如下
字符 Java类型 C类型
V void void
Z jboolean boolean
I jint int
J jlong long
D jdouble double
F jfloat float
B jbyte byte
C jchar char
S jshort short