JNI方法数组和引用

2017-11-01  本文已影响0人  hiandg

JNI方法

步骤:
1.获取jclass
2.获取方法ID;jmethodID
3.jni调用java的方法

extern "C"
JNIEXPORT jstring JNICALL
Java_com_ybj_jnin_MainActivity_getMethod(JNIEnv *env, jobject instance) {

    // TODO
    //jobject obj
    jclass _jclas = env->GetObjectClass(instance);
    //(jclass clazz, const char* name, const char* sig)
    jmethodID _jmethodID = env->GetMethodID(_jclas,"getName","()Ljava/lang/String;");
    //jni 调用java的方法
    //(jobject obj, jmethodID methodID, ...)
    jstring str = (jstring) env->CallObjectMethod(instance, _jmethodID);
    char * string = (char *) env->GetStringUTFChars(str, NULL);
    char text[20] = "success";
    //(char* _Nonnull __restrict, const char* _Nonnull __restrict)
    char * finalResult = strcat(string,text);

    return env->NewStringUTF(finalResult);
}

数组

步骤:
1.获取数组元素
2.获取数组长度
3.释放元素

//首先将a强制声明为指向整数的指针,读取指针对应的整数
int compare(const void* a, const void* b){
    return (*(int*)a - *(int*)b);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_ybj_jnin_MainActivity_getArray(JNIEnv *env, jobject instance, jintArray arrays_) {
    jint *arrays = env->GetIntArrayElements(arrays_, NULL);
    //获取数组长度
    //(jarray array)
    int _len = env->GetArrayLength(arrays_);
    //(void*, size_t, size_t, int (*)(const void*, const void*))第三个参数需要强转
    qsort(arrays,_len, sizeof(int),compare);
    // TODO

    env->ReleaseIntArrayElements(arrays_, arrays, 0);
}

引用(解决JVM回收JNI对象)

-全局引用
调用NewGlobalRef基于局部引用创建。会阻止GC回收所引用的对象。可以跨方法,跨线程使用。JVM不会自动释放。必须手动调用DeleteGlobalRef手动释放

-弱全局引用
与全局引用不一样的是,弱全局引用:
节省内存,在内存不足时可以是释放所引用的对象。
可以引用一个不常用的对象,如果为NULL的时候(被回收了),可以手动再临时创建一个。

extern "C"
JNIEXPORT void JNICALL
Java_com_ybj_jnin_MainActivity_getLocalReference(JNIEnv *env, jobject instance) {
    //模拟一个循环
    for (int i = 0; i < 100; ++i) {
        //(const char* name)
        jclass  _jclass = env->FindClass("java/util/Date");
        jobject _jobj = env->NewObject(_jclass,env->GetMethodID(_jclass,"<init>","()v"));
        //对象的操作
        env->DeleteLocalRef(_jobj);
    }
    // TODO

}

JNI调用构造函数

传入“<init>”作为方法名,“V”作为返回类型。

上一篇下一篇

猜你喜欢

热点阅读