这期内容当中小编将会给大家带来有关Android JNI 调用时缓存字段和方法ID,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
使用时缓存
使用时缓存,就是在调用时查找一次,然后将它缓存成 static 变量,这样下次调用时就已经被初始化过了。
直到内存释放了,才会缓存失效。
extern "C"
JNIEXPORT void JNICALL
Java_com_glumes_cppso_jnioperations_CacheFieldAndMethodOps_staticCacheField(JNIEnv *env, jobject instance, jobject animal) {
static jfieldID fid = NULL; // 声明为 static 变量进行缓存
// 两种方法都行
// jclass cls = env->GetObjectClass(animal);
jclass cls = env->FindClass("com/glumes/cppso/model/Animal");
jstring jstr;
const char *c_str;
// 从缓存中查找
if (fid == NULL) {
fid = env->GetFieldID(cls, "name", "Ljava/lang/String;");
if (fid == NULL) {
return;
}
} else {
LOGD("field id is cached");
}
jstr = (jstring) env->GetObjectField(animal, fid);
c_str = env->GetStringUTFChars(jstr, NULL);
if (c_str == NULL) {
return;
}
env->ReleaseStringUTFChars(jstr, c_str);
jstr = env->NewStringUTF("new name");
if (jstr == NULL) {
return;
}
env->SetObjectField(animal, fid, jstr);
}
通过声明为 static 变量进行缓存。但这种缓存方式显然有弊端,当多个调用者同时调用时,就会出现缓存多次的情况,并且每次调用时都要检查是否缓存过了。
初始化时缓存
在初始化时缓存,就是在类加载时,进行缓存。当类被加载进内存时,会先调用类的静态代码块,所以可以在类的静态代码块中进行缓存。
比如:
public class CacheFieldAndMethodOps extends BaseOperation {
static {
initCacheMethodId(); // 静态代码块中进行缓存
}
private static native void initCacheMethodId();
}
在静态代码块中,可以将所需要的字段 id 或者方法 id 缓存成全局变量。
具体代码如下:
// 全局变量,作为缓存方法 id
jmethodID InstanceMethodCache;
// 初始化加载时缓存方法 id
extern "C"
JNIEXPORT void JNICALL
Java_com_glumes_cppso_jnioperations_CacheFieldAndMethodOps_initCacheMethodId(JNIEnv *env, jclass type) {
jclass cls = env->FindClass("com/glumes/cppso/model/Animal");
InstanceMethodCache = env->GetMethodID(cls, "getName", "()Ljava/lang/String;");
}
在 JNI 中直接将方法 id 缓存成全局变量了,这样再调用时,就不要再进行一次查找了,并且避免了多个线程同时调用会多次查找的情况。
extern "C"
JNIEXPORT void JNICALL
Java_com_glumes_cppso_jnioperations_CacheFieldAndMethodOps_callCacheMethod(JNIEnv *env, jobject instance, jobject animal) {
jstring name = (jstring) env->CallObjectMethod(animal, InstanceMethodCache);
const char *c_name = env->GetStringUTFChars(name, NULL);
LOGD("call cache method and value is %s", c_name);
}
上述就是小编为大家分享的Android JNI 调用时缓存字段和方法ID了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注天达云行业资讯频道。