JNI 多线程
一、概述
JNI编程和Linux上的C/C++编程还是挺相似的,每次java调用JNI中的函数时都会传入有关JVM的一些参数(如JNIEnv,jobject),每次JNI回调java中的方法时都要通过JVM的有关参数来实现,当在JNI中涉及到多线程的话还是有一些不一样的地方,就是要在子线程函数里使用AttachCurrentThread()和DetachCurrentThread()这两个函数,在这两个函数之间加入回调java方法所需要的代码。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h> #include<jni.h>
#include<android/log.h> #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__)) //线程数
#define NUMTHREADS 5 //全局变量
JavaVM *g_jvm = NULL;
jobject g_obj = NULL; void *thread_fun(void* arg)
{
JNIEnv *env;
jclass cls;
jmethodID mid; //Attach主线程
if((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK)
{
LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
return NULL;
}
//找到对应的类
cls = (*env)->GetObjectClass(env,g_obj);
if(cls == NULL)
{
LOGE("FindClass() Error.....");
goto error;
}
//再获得类中的方法
mid = (*env)->GetStaticMethodID(env, cls, "fromJNI", "(I)V");
if (mid == NULL)
{
LOGE("GetMethodID() Error.....");
goto error;
}
//最后调用java中的静态方法
(*env)->CallStaticVoidMethod(env, cls, mid ,(int)arg); error:
//Detach主线程
if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK)
{
LOGE("%s: DetachCurrentThread() failed", __FUNCTION__);
} pthread_exit(0);
} //由java调用以创建子线程
JNIEXPORT void Java_com_nan_thread_MyThreadActivity_mainThread( JNIEnv* env, jobject obj)
{
int i;
pthread_t pt[NUMTHREADS]; for (i = 0; i < NUMTHREADS; i++)
//创建子线程
pthread_create(&pt[i], NULL, &thread_fun, (void *)i);
} //由java调用来建立JNI环境
JNIEXPORT void Java_com_nan_thread_MyThreadActivity_setJNIEnv( JNIEnv* env, jobject obj)
{
//保存全局JVM以便在子线程中使用
(*env)->GetJavaVM(env,&g_jvm);
//不能直接赋值(g_obj = obj)
g_obj = (*env)->NewGlobalRef(env,obj);
} //当动态库被加载时这个函数被系统调用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv* env = NULL;
jint result = -1; //获取JNI版本
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
{
LOGE("GetEnv failed!");
return result;
} return JNI_VERSION_1_4;
}
JNI 多线程的更多相关文章
- Android NDK开发----- JNI多线程
一.概述 JNI编程和Linux上的C/C++编程还是挺相似的,每次java调用JNI中的函数时都会传入有关JVM的一些参数(如JNIEnv,jobject),每次JNI回调java中的方法时都要通过 ...
- NDK学习笔记-JNI多线程
前面讲到记录到ffmpeg音视频解码的时候,采用的是在主线程中进行操作,这样是不行的,在学习了POSIX多线程操作以后,就可以实现其在子线程中解码了,也可以实现音视频同步了 简单示例 在native实 ...
- 解决JNI native 线程不能正常退出的问题
本人刚涉足学习C++ 安卓 java,遇到这个棘手的问题,多谢博客园作者lknlfy 看了你的博客解决了这个问题,此文转发, 方便日后学习 以下内容转自lknlfy作者博客 传送门:http:// ...
- Jni的Jclass JmethodID JfrieldID的差异
Jni的Jclass JmethodID JfrieldID 这三者都是java类别的属性,本质上都是指标(Pointer).透过这些指标就能快速调用java类别的函数,或存取对象的属性值.在该类别被 ...
- Java Native Interface 五 JNI里的多线程与JNI方法的注册
本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 JNI里的多线程 在本地方法里写有关多线程的 ...
- JNI与多线程
在android开发过程中,由于主线程要聚焦于UI交互,为了软件运行流畅必然要用到很多多线程技术.而在JNI机制中专门提供了一些避免线程冲突的函数.了解.学习并掌握如何避免线程冲突问题是一个程序猿的必 ...
- 怎样在多线程中使用JNI?
假设你想了解JNI在怎样在多线程下使用 假设你在子线程使用JNI时遇到findClass不能找到目标Class,而在主线程下却能找到该Class的问题.或是GetEnv返回NULL的问题 假设你想多学 ...
- Android JNI与多线程
Java通过JNI调用本地C++代码是在同一个线程中的同步调用. JNI中如果新建的线程调用java的代码,那么java代码是运行在JNI线程中的:但是,如果调用UI相关的代码时需要与java主线程通 ...
- Jni本地多线程回调Java函数,env->findClass()失败。
遇到的问题,Native层本地多线程回调Java函数时env->findClass()失败. 前面的代码是这样的在 JNI_OnLoad记录全局变量g_vm static JavaVM* g_v ...
随机推荐
- 《Pro Git》学习笔记
1.Git远程模型示意图 Remote:远程仓库 Repository:本地仓库 Index:暂存区 workspace:当前工作区 2.取得Git仓库 2.1 初始化新仓库 git init ...
- Opencv——将摄像头拍摄写成视频文件
这里主要利用了Opencv打开摄像头的代码,以及写入视频的函数,只是这里要注意的是摄像头好像没有帧率,在cvCreateVideoWriter,时要自己设置 #include"cv.h&qu ...
- 转-----EasyCHM制作教程
希望以后自己的笔记能够整理成 chm 格式的文档 制作过CHM帮助文件的同志们可能都遇到过以下两个问题: 1.制作好的CHM文件图像.公式不显示. 2.制作好的CHM文件在自己电脑上能显示,在别人电脑 ...
- WinForm程序中两份mdf文件问题的解决
在项目中用程序中嵌入mdf文件的方式来进行SQLServer数据库开发非常方便,用来发布开源项目等很方便,点击就可以运行,免部署,特别是在教学中用起来更加方便,老师不用先将数据库文件detach再发给 ...
- TCP/IP三次握手
题目: TCP建立连接的过程采用三次握手,已知第三次握手报文的发送序列号为1000,确认序列号为2000,请问第二次握手报文的发送序列号和确认序列号分别为 1999,999 1999,1000 999 ...
- Golden32 别名时中文 报ORA-00911: invalid character错误
查询数据库软件我一般用两个:PL SQL和golden32:使用golden32-之前使用的时候别名为中文是没有任何问题:直到我想将PL SQL汉化(使用中文包chinese.exe),汉化完后再次查 ...
- 【HTTPS】Https和SSL学习笔记(一)
1. 什么是HTTPS 在说HTTPS之前必须要先说一下HTTP.我们平常浏览网页用的就是HTTP协议,HTTP协议之间传输的数据都是明文,这样对于一些敏感信息传输其实是不安全的,很容易被恶意窃取.应 ...
- 使用struts+spring+hibernate组装web应用
这篇文章将讨论怎样组合几个着名的框架去做到松耦合的目的,怎样建立你的构架,怎样让你的各个应用层保持一致.富于挑战的是:组合这些框架使得每一层都以一种松耦合的方式彼此沟通,而与底层的技术无关.这篇文章将 ...
- 第二十三篇、使用NSURLSession时需要注意一个内存泄漏问题
如图1代码所示,初始化一个NSURLSession临时实例对象并由它发起一个网络请求.我们通过Instruments的Leaks工具会发现其存在内存泄漏和循环引用的地方,如图2所示. 通过NSURLS ...
- java中的异常处理机制_finally的使用
finally总结: finally代码块:定义一定执行的代码 通常用于关闭资源或者某些一定执行的代码 实例1:finally功能演示 class FuShuException extends Exc ...