JNI多线程和全局引用

  • JNI 支持三种不透明引用:局部引用( local references),全局引用(global references)和弱全局引用( weak global references)。
  • 局部和全局引用有不同的生命周期,本地应用被自动释放,而全局应用和弱全局引用仅在显式调用释放命令时释放。
  • 一个局部和全局引用保持引用对象不被garbage内存回收。另一方面,弱全局引用是允许引用对象被garbage内存回收的。
  • 并非所有的引用都能在任何上下文中被使用。例如,在创建引用的native函数返回后使用这个引用是不合法的。
  • 多线程env 需要调用(*javaVM)>AttachCurrentThread(javaVM,&env,NULL);
#include "com_dongnaoedu_androidlinux_PosixThread.h"
#include <stdio.h>
#include <pthread.h>
#include <android/log.h>
#include <unistd.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"jason",FORMAT,##__VA_ARGS__);
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"jason",FORMAT,##__VA_ARGS__);

JavaVM *javaVM;
jobject uuidutils_class_global;
jmethodID uuidutils_get_mid;

//动态库加载时会执行
//兼容Android SDK 2.2之后,2.2没有这个函数
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){
    LOGI("%s","JNI_OnLoad");
    javaVM = vm;
    return JNI_VERSION_1_4;
}

void* th_fun(void* arg){
    int i;
    for (i = 0; i < 5; i++) {
        JNIEnv* env;
        //关联参数
        //JavaVMAttachArgs args = {JNI_VERSION_1_4, "my_thread", NULL};
        //(*javaVM)->AttachCurrentThread(javaVM,&env,&args);
        (*javaVM)->AttachCurrentThread(javaVM,&env,NULL);
        jobject uuid_jstr = (*env)->CallStaticObjectMethod(env,uuidutils_class_global,uuidutils_get_mid);
        const char* uuid_cstr = (*env)->GetStringUTFChars(env,uuid_jstr,NULL);
        LOGI("uuid:%s",uuid_cstr);
        //退出线程
        if(i == 4){
            goto end;
        }
        sleep(1);
    }
end:
    //取消关联
    (*javaVM)->DetachCurrentThread(javaVM);
    pthread_exit((void*)0);

}

//JavaVM 代表的是Java虚拟机,所有的工作都是从JavaVM开始
//可以通过JavaVM获取到每个线程关联的JNIEnv

//如何获取JavaVM?
//1.在JNI_OnLoad函数中获取
//2.(*env)->GetJavaVM(env,&javaVM);


//每个线程都有独立的JNIEnv


//初始化
JNIEXPORT void JNICALL Java_com_dongnaoedu_androidlinux_PosixThread_init
  (JNIEnv *env, jobject jobj){
    //获取class必须要在主线程中
    jclass uuidutils_class_tmp = (*env)->FindClass(env,"com/dongnaoedu/androidlinux/UUIDUtils");
    //创建全局引用
    uuidutils_class_global = (*env)->NewGlobalRef(env,uuidutils_class_tmp);
    //获取jmethodId也可以在子线程中
    uuidutils_get_mid = (*env)->GetStaticMethodID(env,uuidutils_class_global,"get","()Ljava/lang/String;");

}

//销毁
JNIEXPORT void JNICALL Java_com_dongnaoedu_androidlinux_PosixThread_destroy
  (JNIEnv *env, jobject jobj){
    //释放全局引用
    (*env)->DeleteGlobalRef(env,uuidutils_class_global);
}

JNIEXPORT void JNICALL Java_com_dongnaoedu_androidlinux_PosixThread_pthread
  (JNIEnv *env, jobject jobj){
    //(*env)->GetJavaVM(env,&javaVM);
    //创建多线程
    pthread_t tid;
    pthread_create(&tid, NULL,th_fun,(void*)"NO1");

}



©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容