• 假设你想了解JNI在怎样在多线程下使用
  • 假设你在子线程使用JNI时遇到findClass不能找到目标Class,而在主线程下却能找到该Class的问题。或是GetEnv返回NULL的问题
  • 假设你想多学点编程技术的话
那么,这篇文章就是为你而写的, :)
近期工作中遇到这么个问题:c++代码须要调用Android的API来做一个比較耗时的任务,由于有点耗时,希望能有个进度条显示给用户,非常自然地,我创建了一个子线程用来执行这个耗时的任务,依照平时写法,结果一执行,GetEnv获取失败了。网上查找一番,官方说明有这么句话:
If the current thread is not attached to the VM, sets *env to NULL, and returns JNI_EDETACHED. If the specified version is not supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise, sets *env to the appropriate interface, and returns JNI_OK.
调试后找到了原因,the current thread is not attached。 原来子线程函数里须要使用AttachCurrentThread()和DetachCurrentThread()这两个函数。没错,你须要gJvm->AttachCurrentThread(&env, NULL);来获取env,这样写之后,以为万事大吉了,结果findClass出错了,没有找到目标类,但是我千真万确地记得在主线程里这么写是没有问题的。env没有问题了,这回又哪里出错了呢?上网google一番,噢,不正确,google被墙了,是用bing查找一番后,总算有些眉目了。
首先确保你的class name写对了,以包名开头,并用反斜杠隔开。假设class name没有错,那么应该是class loader的问题了。解决方法是你先在主线程中获取该class,而且将其保存为全局变量,以便其它线程使用。
jclass tmp = env->FindClass("com/example/company/MyClass");  
myClass = (jclass)env->NewGlobalRef(tmp);
在子线程中,
mid = env->GetStaticMethodID(cls, "fromJNI", "(I)V");
if (mid != NULL)
{
    env->CallStaticVoidMethod(env, cls, mid, i);
}
当然,也有其它解决方法,至少我使用这样的方法成功了。而接下来在java中调用c++的代码就比較顺利了,木有碰到问题了。
总结:
1.在JNI_OnLoad中,保存JavaVM*,这是跨线程的,持久有效的,而JNIEnv*则是当前线程有效的。一旦启动线程,用AttachCurrentThread方法获得env。
2.通过JavaVM*和JNIEnv能够查找到jclass。
3.把jclass转成全局引用,使其跨线程。
4.然后就能够正常地调用你想调用的方法了。
5.用完后,别忘了delete掉创建的全局引用和调用DetachCurrentThread方法。
【转载请注明出处:http://blog.csdn.net/booirror/article/details/37778283】

怎样在多线程中使用JNI?相关推荐

  1. 【Linux】多线程中使用fork()

    (最核心的东西我在下面用红色字体标出来了,理解了那块,这些东西都是就理解了!) 在本篇文章开始之前,需要大家先了解线程和进程,这位大哥讲的言简意赅:进程和线程的主要区别(总结)_kuangsongha ...

  2. java闭合数据_java多线程中线程封闭详解

    线程封闭的概念 访问共享变量时,通常要使用同步,所以避免使用同步的方法就是减少共享数据的使用,这种技术就是线程封闭. 实现线程封闭的方法 1:ad-hoc线程封闭 这是完全靠实现者控制的线程封闭,他的 ...

  3. java多线程中的join方法详解

    java多线程中的join方法详解 方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答. 自从接触Java多线程,一直对Join理解不了.JDK是这样说的:join p ...

  4. 了解多线程中的yield

    2019独角兽企业重金招聘Python工程师标准>>> 最近在学习多线程这一块,发现里面有好多让人产生误区的地方,今天我来分析下java多线程中的yield功能,希望其他朋友也可以从 ...

  5. 解决DataGridView在多线程中无法显示滚动条的问题

    解决DataGridView在多线程中无法显示滚动条的问题 参考文章: (1)解决DataGridView在多线程中无法显示滚动条的问题 (2)https://www.cnblogs.com/roph ...

  6. VMware 虚拟化编程(8) — 多线程中的 VixDiskLib

    目录 目录 前文列表 多线程注意事项 多线程中的 VixDiskLib 前文列表 VMware 虚拟化编程(1) - VMDK/VDDK/VixDiskLib/VADP 概念简析 VMware 虚拟化 ...

  7. 如何在多线程中调用winform窗体控件2——实例篇

    如何在多线程中调用winform窗体控件2--实例篇 针对之前文章<如何在多线程中调用winform窗体控件>,下面举个我项目中的实际案例,这是一个我自定义控件在异步设置焦点时的代码.在新 ...

  8. android串口补位,Rust多线程中的消息传递机制

    代码说话. use std::thread; use std::sync::mpsc; use std::time::Duration; fn main() { let (tx, rx) = mpsc ...

  9. JAVA多线程中join()方法的详细分析

    虽然关于讨论线程join()方法的博客已经非常极其特别多了,但是前几天我有一个困惑却没有能够得到详细解释,就是当系统中正在运行多个线程时,join()到底是暂停了哪些线程,大部分博客给的例子看起来都像 ...

最新文章

  1. 利用动态加载模板,配合ajax实现无刷新操作
  2. 二维“有序”数组查找问题
  3. swift 4 字符串截取
  4. JAVA命令符找不到符号_[转]Java命令行编译文件时出现的错误,找不到符号或软件包不存在等...
  5. navicate连接远程数据库
  6. 个人信息保护呼吁“基本法”
  7. C语言课后习题(25)
  8. mysql char 二进制_SQL:char 和 varchar、binary 和 varbinary、二进制字符串、严格模式、汉字编码方式...
  9. 基于人脸识别的商业大数据2
  10. 剑指offer -- 反转链表
  11. 阅读笔记-JavaScript学习指南
  12. linux下ssh安装教程,linux安装ssh
  13. 开源进销存管理系统学习教程
  14. 函数对称性常见公式_初中函数公式大全
  15. Lightroom Classic CC 2019 for Mac(lr cc 2019 mac)
  16. VS code如何下载并配置C语言(详细)
  17. ecu故障现象_案例-报ECU系统软件重置故障处理方案
  18. 三相差分编码器转成脉冲信号或集电极开路转换模块
  19. 2020Android不死我不倒,作为一个程序员,你觉得最大的悲哀是什么
  20. 电脑怎么录屏幕视频带声音?电脑录屏教程介绍

热门文章

  1. 桌面程序调用Web Service应用实例
  2. 认识ASP.NET配置文件Web.config
  3. ARTS打卡计划第四周-ALGORITHM
  4. (转)JS之——解决IE6、7、8使用JSON.stringify报JSON未定义错误的问题
  5. Laravel 单设备登录
  6. 使用visual studio code调试php代码
  7. 消息称中国商务部已批准高通收购恩智浦
  8. Freescale 基于IMX536处理器的Dialog DA9053电源管理参考设计
  9. webbench网络压力测试源码
  10. php-5.2.3.tar.bz2.gz 的解压方法