android JNI 多线程 C函数回调
JNIEnv *env指针不可为多个线程共用,但是java虚拟机的JavaVM指针是整个jvm公用的,我们可以通过JavaVM来得到当前线程的JNIEnv指针.
示例代码:
#include
static JavaVM* g_vm = NULL;
static jclass g_mainActivityClass = NULL;
static jmethodID g_ID = NULL;
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv * env = NULL;
if(g_vm == NULL){
g_vm = vm;
}
if ( (*g_vm)->GetEnv(vm,(void**)&env, JNI_VERSION_1_2) != JNI_OK) {
LOGD("ERROR: GetEnv failed");
return -1;
};
jclass mainActivityClass = (*env)->FindClass(env,"com/ht/htvideodemo/activity/MainActivity");
if( mainActivityClass == NULL){
return -2;
}
g_mainActivityClass = (*env)->NewGlobalRef(env,mainActivityClass);
return JNI_VERSION_1_2;
}
//C函数的回调
jint result;
JNIEnv * env = NULL;
if(g_vm == NULL){return;}
result = (*g_vm)->AttachCurrentThread(g_vm,&env, NULL);
if(result == JNI_OK) {
if (g_mainActivityClass != NULL){
jclass clazz = (*env)->GetObjectClass(env,g_mainActivityClass);
if(mpkt->nMediaType == HTC_MEDIA_VIDEO){
int size = mpkt->nSize;
jbyteArray bytearray;
bytearray = (*env)->NewByteArray(env,size);
(*env)->SetByteArrayRegion(env,bytearray,0,size,mpkt->pBuffer);
g_ID = (*env)->GetStaticMethodID(env,g_mainActivityClass,"test","([B)V");
(*env)->CallStaticVoidMethod(env,g_mainActivityClass,g_ID,bytearray);
}
}
}
(*g_vm)->DetachCurrentThread(g_vm); //释放线程,否则会导致内存泄漏
更多相关文章
- Android框架保证View更新必须在主线程的解读
- android HorizontalScrollView实现滚动状态监听
- 编写android加载图片的程序时,遇到了内存泄露问题!
- ANDROID 隐藏 任务栏 systemui systembar 全屏显示
- Handler Looper Message源码研究
- 线程间通信----Handler
- Android延迟执行PostDelayed
- RxJava学习笔记(Schedulers)
- Android异步更新UI的方式之使用runOnUiThread(action)方法