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