访问域
Java 有两类域:实例域和静态域。类的每个实例都有自己的实例域副本,而一个类所有实例共享一个静态域。如下程序:
public class JavaClass{
/** 实例域 */
private String instanceField = "Instantce Field";
/** 静态域 */
private static String staticField = "Static Field";
}
JNI 提供了访问两类域的函数。
1.获取域ID
通过给定实例的 class 对象获取域 ID,用 GetObjectClass 函数获取 class 对象。如下代码:
jclass clazz = (*env) -> GetObjectClass(env,instance);
GetFieldID 获取实例域ID:
jfieldID instanceFieldId = (*env)->GetFieldID(env,clazz,"instanceField","Ljava/lang/String;");
GetStaticFieldID 获取静态域ID:
jfieldID instanceFieldId = (*env)->GetStaticFieldID(env,clazz,"staticField","Ljava/lang/String;");
上面两个方法的第三个参数代表要获取的域名称,第四个参数表示域类型,这里 "Ljava/lang/String;" 表示String型,在后面会详细讲。为了提高应用程序的性能,可以缓存域 ID,一般总是缓存使用频率最高的域 ID。
2.获取域
在获取域 ID 以后,可以用 Get<type>Field 函数获得实际的实例域,如下程序:
/** 获取实例域 */
jstring instanceField = (*env)->GetObjectField(env,instance,instanceFieldId);
/** 获取静态域 */
jstring staticField = (*env)->GetStaticObjectField(env,clazz,staticFieldId);
获取单个域值需要调用两到三个 JNI 函数,原生代码回到 Java 中获取每个单独的域值,这个应用程序增加了额外的负担,进而导致性能下降。建议将所有需要的参数传递给原生方法调用,而不是让原生代码回到 Java 中。在内存溢出的情况下,这些函数均返回NULL,此时原生代码奖不再继续执行。
调用方法
与域一样 Java 中又两类方法: 实例方法和静态方法。
public class JavaClass{
<span style="white-space:pre"> </span>private String instanceMethod{
<span style="white-space:pre"> </span>return "Instance Method";
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>publice static String staticMethod{
<span style="white-space:pre"> </span>return "Static Method";
<span style="white-space:pre"> </span>}
....
1.获取方法 ID
通过给定实例的 class 对象获取方法 ID。用 GetMethod 函数获取实例方法的方法 ID。
jmethodID instatnceMethodId;
instanceMethodId = (*env) -> GetMethodID(env, clazz,"instatnceMethod","()Ljava/lang/String;");
用 GetStaticMethodID 函数获取静态域的方法 ID。
jmethodID staticMethodId;
staticMethodId= (*env) -> GetStaticMethodID(env, clazz,"staticMethod","()Ljava/lang/String;");
通过 Call<Type>Method 类函数调用实例的实例方法。
jstring instanceMethodResult;
instanceMethodResult = (*env) -> CallStringMethod(env,instatnce,instatnceMethodId);
通过 CallStatic<Type>Field 类函数调用静态方法。
jstring staticMethodResult;
staticMethodResult = (*env) -> CallStaticStringMethod(env,clazz,staticMethodId);
域和方法描述符
(未完待续)
Android NDK编程浅入深出之--了解NDK
Android NDK编程浅入深出之--Android.mk