• 假设你想了解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方法。


怎样在多线程中使用JNI?的更多相关文章

  1. c#初学-多线程中lock用法的经典实例

    本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被 ...

  2. iOS多线程中,队列和执行的排列组合结果分析

    本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...

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

    在多线程中对DataGridView指定 DataSource 来填充数据,更新数据的时候,会导致DataGridView出现假死,显示错误或者滚动条无法显示的问题,在保证了DataGridView的 ...

  4. iOS开发——多线程OC篇&多线程中的单例

    多线程中的单例 #import "DemoObj.h" @implementation DemoObj static DemoObj *instance; // 在iOS中,所有对 ...

  5. c#语言-多线程中的锁系统(一)

    介绍 平常在多线程开发中,总避免不了线程同步.本篇就对net多线程中的锁系统做个简单描述.   目录 一:lock.Monitor        1:基础.        2: 作用域.       ...

  6. [C#学习]在多线程中如何调用Winform[转]

    问题的产生: 我的WinForm程序中有一个用于更新主窗口的工作线程(worker thread),但文档中却提示我不能在多线程中调用这个form(为什么?),而事实上我在调用时程序常常会崩掉.请问如 ...

  7. Java多线程中易混淆的概念

    概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...

  8. Java多线程中变量的可见性

    之所以写这篇博客, 是因为在csdn上看到一个帖子问的就是这个问题. 废话不多说, 我们先看看他的代码(为了减少代码量, 我将创建线程并启动的部分修改为使用方法引用). 1 2 3 4 5 6 7 8 ...

  9. android中使用jni对字符串加解密实现分析

    android中使用jni对字符串加解密实现分析 近期项目有个需求.就是要对用户的敏感信息进行加密处理,比方用户的账户password,手机号等私密信息.在java中,就对字符串的加解密我们能够使用A ...

随机推荐

  1. 自己写shell命令pwd

    思维:(1)得到"."的i节点号,叫n(使用stat) (2)chdir ..(使用chdir) (3)找到inode号为n的节点,得到其文件名称. 反复上述操作直到当前文件夹&q ...

  2. svn创建并应用补丁

    有时,我们不能提交临时局部变化,而我们需要回滚到svn最新的版本号.然,这些变化,我们要保持.提交或发送给其他同事的未来review. 怎么做?非常easy,只需要两个步骤: (1)创建一个补丁文件并 ...

  3. T-SQL基础(5) - 表表达式

    1.派生表(derived table)select YEAR(orderdate) as orderyear, COUNT(distinct custid) as numcustsfrom Sale ...

  4. java计算器 图形用户界面 精简版

    package com.rgy.entity; import java.awt.*; import java.awt.event.*; @SuppressWarnings("serial&q ...

  5. 删CentOS / RHEL库和配置文件(Repositories and configuraiton files)

    1 删除库简介 随着root权限执行以下的命令: # cd /etc/yum.repos.d/ 列出全部库(repo) #ls CentOS-Base.repo epel.repo mirrors-r ...

  6. android imageButton 透明图片

    在Android有许多不规则button.例如: 这个时候,我们假设想做成不规则button的话.第一步就是搞一张边缘透明的png图片,然后用src指定到他.这个时候我们会发现,还没有达到要的效果.还 ...

  7. POJ 3422 Kaka&#39;s Matrix Travels(费用流)

    POJ 3422 Kaka's Matrix Travels 题目链接 题意:一个矩阵.从左上角往右下角走k趟,每次走过数字就变成0,而且获得这个数字,要求走完之后,所获得数字之和最大 思路:有点类似 ...

  8. 【iOS】文件上传小记

    iOS由该系统提供API可以实现可以实现文件的上传和下载,有两种方法来. NSURLConnection与NSURLSession. 当中NSURLConnection是使用非常久的的一种方式.NSU ...

  9. ASP.NET5

    ASP.NET5 2015年11月30日, ASP.NET 5 RC1 已经发布,本文尝试了一下ASP.NET5项目的创见一发布到IIS.开发环境,win10 64位,visual studio201 ...

  10. table插入标签form标记怪现象

    最近帮朋友处理问题,它无法提交表单,得到一些时间,我发现了一个奇怪的问题 <table> <form action="upload.php" method=&qu ...