JNI由浅入深_8_JNI缓存字段和方法ID
来源:互联网 发布:淘宝卖家新手入门教程 编辑:程序博客网 时间:2024/06/06 21:00
获取字段ID和方法ID时,需要用字段、方法的名字和描述符进行一个检索。检索过程相对比较费时,因此本节讨论用缓存技术来减少这个过程带来的消耗。缓存字段ID和方法ID的方法主要有两种。两种区别主要在于缓存发生的时刻,是在字段ID和方法ID被使用的时候,还是定义字段和方法的类静态初始化的时候。
1、使用时缓存
字段ID和方法ID可以在字段的值被访问或者方法被回调的时候缓存起来。下面的代码中把字段ID存储在静态变量当中,这样当本地方法被重复调用时,不必重新搜索字段ID。
JNIEXPORT void JNICALL Java_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj) { static jfieldID fid_s = NULL; /* cached field ID for s */ jclass cls = (*env)->GetObjectClass(env, obj); jstring jstr; const char *str; if (fid_s == NULL) { fid_s = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); if (fid_s == NULL) { return; /* exception already thrown */ } } printf("In C:\n"); jstr = (*env)->GetObjectField(env, obj, fid_s); str = (*env)->GetStringUTFChars(env, jstr, NULL); if (str == NULL) { return; /* out of memory */ } printf(" c.s = \"%s\"\n", str); (*env)->ReleaseStringUTFChars(env, jstr, str); jstr = (*env)->NewStringUTF(env, "123"); if (jstr == NULL) { return; /* out of memory */ } (*env)->SetObjectField(env, obj, fid_s, jstr); }
2、初始化缓存
许多情况下,在字段ID和方法ID被使用前就初始化是很方便的。VM在调用一个类的方法和字段之前,都会执行类的静态初始化过程,所以在静态初始化该类的过程中计算并缓存字段ID和方法ID是个不错的选择。
例如,为了缓存InstanceMethodCall.callback的方法ID,我们引入了一个新的本地方法initIDs,这个方法在InstanceMethodCall的静态初始化过程中被调用。/** * 缓存ID */jmethodID callbackStatic;JNIEXPORT void JNICALL Java_com_example_jniandroid_service_CFunction_callJniNative2(JNIEnv * env, jobject obj) {LOGI("缓存了id...");(*env)->CallStaticVoidMethod(env, obj, callbackStatic);}JNIEXPORT void JNICALL Java_com_example_jniandroid_service_CFunction_initIDS(JNIEnv * env, jobject obj) {//调用静态方法jclass cls = (*env)->GetObjectClass(env, obj);callbackStatic = (*env)->GetStaticMethodID(env, cls, "callbackStatic", "()V");}
两种缓存ID的方式之间的对比
如果JNI程序员不能控制方法和字段所在的类的源码的话,在使用时缓存是个合理的方案。例如在MyNewString当中,我们不能在String类中插入一个initIDs方法。
比起静态初始时缓存来说,使用时缓存有一些缺点:
1、使用时缓存的话,每次使用时都要检查一下。
2、方法ID和字段ID在类被unload时就会失效,如果你在使用时缓存ID,你必须确保只要本地代码依赖于这个ID的值,那么这个类不被会unload(下一章演示了如何通过使用JNI函数创建一个类引用来防止类被unload)。另一方面,如果缓存发生在静态初始化时,当类被unload和reload时,ID会被重新计算。
因此,尽可能在静态初始化时缓存字段ID和方法ID。
1 0
- JNI由浅入深_8_JNI缓存字段和方法ID
- 缓存字段和方法ID
- JNI由浅入深_7_c调用Java方法一
- JNI由浅入深
- JNI编程指南-第四章 字段和方法
- JNI操作JAVA中操作字段和方法的效率
- Android NDK(五):JNI字段和方法
- JNI由浅入深_3_Hello World
- JNI由浅入深_10_JNI 综合开发
- 合并id字段和value
- Java中JNI的使用详解第六篇:C/C++中的引用类型和Id的缓存
- java学习之JNI学习二 取得属性和方法的ID
- JNI由浅入深_2_C语言基础
- JNI由浅入深_4_JNI基础知识详解
- JNI由浅入深_9_JNI 异常处理
- android开发之JNI由浅入深
- JNI官方规范中文版——如何访问Java中的字段和方法
- JNI官方规范中文版——如何访问Java中的字段和方法
- JavaEE事务
- bzoj 1303 中位数
- 避免Activity启动时某个控件马上获取焦点(如EditText/Gallery等)
- Flex 跨域访问解决方案
- usb camera 成功
- JNI由浅入深_8_JNI缓存字段和方法ID
- c#建立验证码图片
- java 拦截器和过滤器区别(转载)
- 获得PostgreSQL安装包和主要参考资料
- 解决eclipse下载超慢的问题
- 1076. Forwards on Weibo (30)
- android 自定义Titlebar
- 深度学习概述
- CherryPy上传文件