如何在JNI中使用线程

 我来答
育知同创教育
2016-08-15 · 百度知道合伙人官方认证企业
育知同创教育
1【专注:Python+人工智能|Java大数据|HTML5培训】 2【免费提供名师直播课堂、公开课及视频教程】 3【地址:北京市昌平区三旗百汇物美大卖场2层,微信公众号:yuzhitc】
向TA提问
展开全部
JNIEnv* g_env;
jobject g_thiz;
JavaVM *g_jvm;
void* thread_get_str(void * argv) {
(g_jvm)->AttachCurrentThread(&g_env, NULL);
LOGE("log in another thread!!!!!!!!!!");
jclass clazz = (g_env)->GetObjectClass(g_thiz);
jfieldID fid = (g_env)->GetFieldID(clazz, "mInstanceName", "Ljava/lang/String;");
jstring jstr = (jstring)(g_env)->GetObjectField(g_thiz, fid);
LOGE("this message is from other thread of c++ %s", (g_env)->GetStringUTFChars(jstr, NULL));
(g_jvm)->DetachCurrentThread();
}

void threadTest(JNIEnv* env, jobject thiz) {
if (g_thiz) {
(g_env)->DeleteGlobalRef(g_thiz);
}
g_thiz = (env)->NewGlobalRef(thiz);
g_env = env;

pthread_t thread;

pthread_create(&thread, NULL, thread_get_str, NULL);

}
看到了么关键是(g_jvm)->AttachCurrentThread(&g_env, NULL); 和(g_jvm)->DetachCurrentThread(); 函数,是把当前的线程绑定到jvm上,我们通过全局变量实现了参数的传递,当然了,其实我们也可以调用AndroidRuntime::getRuntime来获得vm但是比较麻烦,因为有些头文件的配置比较麻烦。至此,我们成功的在c++层使用了线程。

尽管现在中国的工程师还是比较急功近利,总是期望知道是什么,而很少问为什么,但是我觉得一个优秀的工程师应该知道为什么。

首先为什么我们不调用那两个函数就无法使用线程。我的功力有限,简单的看了下,我们JNI函数中的,evn其实是当前线程的环境参数,使用当我们创建新的线程就无法使用了,当我们调用AttachCurrentThread就是为当前线程创建一些环境参数。
1,AttachCurrentThread 调用 attachThread
2, JavaVMAttachArgs argsCopy;
if (args == NULL) {
/* allow the v1.1 calling convention */
argsCopy.version = JNI_VERSION_1_2;
argsCopy.name = NULL;
argsCopy.group = (jobject) dvmGetMainThreadGroup();
} else {
assert(args->version >= JNI_VERSION_1_2);

argsCopy.version = args->version;
argsCopy.name = args->name;
if (args->group != NULL) {
argsCopy.group = (jobject) dvmDecodeIndirectRef(NULL, args->group);
} else {
argsCopy.group = (jobject) dvmGetMainThreadGroup();
}
}

bool result = dvmAttachCurrentThread(&argsCopy, isDaemon);
这里我们copy了当期的环境参数到新的线程中。
然后接下来就创建线程,然后让线程跑起来。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式