Android JNI Java構造方法的實例化和引用類型

首先Dog類,添加構造方法,使構造方法被C++中直接實例化
在這裏插入圖片描述
添加兩個按鈕
在這裏插入圖片描述
在MainActivity中定義兩個native方法testDog和testUnDog,兩個按鈕點擊分別調用這兩個方法
在這裏插入圖片描述

全局引用 和 構造方法實例化:

在這裏插入圖片描述

使用NewGlobalRef來定義dogClass爲全局引用。如果不設置爲全局引用,會隱式釋放 dogClass , dogClass不爲NULL 但 懸空,所以再次點擊“測試引用”按鈕就會報錯。

全局引用必須手動釋放,最後設置dogClass = NULL

// TODO 引用類型 + Java構造方法的實例化
jclass dogClass;
extern "C"
JNIEXPORT void JNICALL
Java_com_hongx_jni_MainActivity_testDog(JNIEnv *env, jobject thiz) {
    // 局部引用:如果在函數裏面,是在棧區,不用回收,函數結束,會自動回收 ,爲了專業性,最好要寫回收
    if (dogClass == NULL) { // 第一次滿足,  第二次不滿足了
        // 局部引用的方式
//        const char * dog_class_str = "com/hongx/jni/Dog";
//        dogClass = env->FindClass(dog_class_str);
        // 解決各個局部引用帶來的問題,全局引用(自己來提升)
        const char *dog_class_str = "com/hongx/jni/Dog";
        jclass temp = env->FindClass(dog_class_str);
        dogClass = static_cast<jclass>(env->NewGlobalRef(temp));
        // 手動釋放全局引用之後,再次點擊,沒有進來
        __android_log_print(ANDROID_LOG_DEBUG, "Dog", "dogClass == NULL");
    }
    // Java構造方法的實例化
    const char *sig = "()V";
    const char *method = "<init>"; // Java構造方法的標識
    jmethodID init = env->GetMethodID(dogClass, method, sig);
    env->NewObject(dogClass, init); // 由於dogClass 是懸空的,直接報錯
    // 會隱式釋放 dogClass  , dogClass不爲NULL, 懸空   同時手動全局釋放一致
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hongx_jni_MainActivity_testUnDog(JNIEnv *env, jobject thiz) {
    if (dogClass != NULL) {
        __android_log_print(ANDROID_LOG_DEBUG, "Dog", "全局應用被釋放了,上面的按鈕不能點擊了,否則報錯");
        env->DeleteGlobalRef(dogClass);
        dogClass = NULL;
    }
    // Studnet * student = new Student; // 堆 必須釋放
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章