★08.缓存属性和方法ID

2017-07-03  本文已影响0人  iDragonfly

简介

用时缓存

简单示例

JNIEXPORT void JNICALL Java_InstanceFieldAccess_accessField(JNIEnv * env, jobject obj) {
    // 静态局部变量以便于一次获取,以后就不必重新获取
    static jfieldID fid_s = NULL;

    jclass cls = (* env)->GetObjectClass(env, obj);

    // 只有从来没获取fid_s才会获取
    if (!fid_s) {
        fid_s = (* env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
        if (!fid_s) {
            return;
        }
    }

    jstring jstr = (* env)->GetObjectField(env, obj, fid_s);
    const char * str = (* env)->GetStringUTFChars(env, jstr, NULL);
    if (!str) {
        return;
    }
    printf("In C: \n");
    printf("c.s = \"%s\"\n", str);
    (* env)->ReleaseStringUTFChars(env, jstr, str);
    jstring newJstr = (* env)->NewStringUTF(env, "123");
    if (!newJstr) {
        return;
    }
    (* env)->SetObjectField(env, obj, fid_s, newJstr);
}

示例解说

优缺点

类静态初始化器缓存

简单示例

public class InstanceMethodCall {
    static {
        System.loadLibrary("InstanceMethodCall");
        // 在类静态初始化代码块中缓存ID
        initIDs();
    }

    public static void main(String args[]) {
        InstanceMethodCall c = new InstanceMethodCall();
        c.nativeMethod();
    }

    // 类静态函数,实现交给原生代码,用于缓存ID
    private static native void initIDs();

    private native void nativeMethod();

    private void callback() {
        System.out.println("In Java");
    }
}
// 创建全局变量,以便于ID可以在多个不同的原生函数中传递
jmethodID MID_InstanceMethodCall_callback;

JNIEXPORT void JNICALL Java_InstanceMethodCall_initIDs(JNIEnv * env, jclass cls) {
    // 获取所有需要缓存的ID到全局变量中
    MID_InstanceMethodCall_callback = (* env)->GetMethodID(env, cls, "callback", "()V");
}

JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod(JNIEnv * env, jobject obj) {
    printf("In C\n");
    // 使用缓存的ID
    (* env)->CallVoidMethod(env, obj, MID_InstanceMethodCall_callback);
}

示例解说

优缺点

两种方法的性能比较

概念

Java/native调用

native/Java调用

上一篇 下一篇

猜你喜欢

热点阅读