2.5.2 操作成员变量(域)和方法
上节通过JNI提供的类操作函数得到了类的引用,通过这个引用便可以操作这个类上提供的方法和变量。JNI用名字和类型签名来识别方法和域(变量)。
注意 Java中习惯将变量称为成员变量,而不是域。这里为了兼容JNI命名规则和Java习惯,将域和变量等价。
从名字和类型签名来操作对象上的域和方法可分为两步。还是以Log系统为例。打开android_util_Log.cpp,找到register_android_util_Log方法,代码如下:
int register_android_util_Log(JNIEnv*env)
{
jclass clazz=env->FindClass("android/util/Log");
levels.debug=env->GetStaticIntField(clazz,
env->GetStaticFieldID(clazz,"DEBUG","I"));
……
}
首先,通过FindClass方法找到android/util/Log的类信息clazz;然后,以clazz为参数调用GetStaticFieldID(clazz,"DEBUG","I"),其中DEBUG是要访问的Java域的名字,I是该Java域的类型签名,即整型。GetStaticFieldID的函数原型如下:
jfieldID GetStaticFieldID(jclass clazz, const charname, const charsig)
该函数返回了一个jfieldID,代表Java成员变量。最后将该jfieldID传给GetStaticIntField方法,得到Java层的成员变量DEBUG的值,即3。
下面是Log.java的源码:
public final class Log{
……
public static final int DEBUG=3;
……
}
JNI调用Java层的方法与此类似,流程是:
FindClass->GetMethodID返回(jmethodID)->Call<Type>Method这里仅提供函数列表,不再详细解释。
表2-4中列出了JNI提供的操作域和方法的函数。