博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题
阅读量:5019 次
发布时间:2019-06-12

本文共 2330 字,大约阅读时间需要 7 分钟。

最近在移植网络摄像机里的p2p库到android平台,需要用到jni,最近在c线程了调用java函数的时候

出现一个问题,假如在同一个线程调用java函数是没问题的,但在一个c线程了调用java函数就出现奔
溃问题,下面就直接贴c线程里调用java函数的流程代码吧:

步骤1. 我这里的应用是,java处理视频播放,在java层写需要调用的函数,例如:

private void recvData(String devid, byte[] data, int nDataType, int nLen){      Log.i(TAG, "recv id:"+devid+", type:"+nDataType+", len:"+nLen);}

步骤2. 在native-lib.cpp中jni层代码如下(注意这是c++代码):

JavaVM* local_JavaVM = NULL;jobject j_obj = NULL;jmethodID j_mid = NULL;JNIEXPORT void JNICALL Java_com_p2p_test_MainActivity_InitP2P (JNIEnv *env, jobject jobj) {        jclass clazz = env->GetObjectClass(jobj);    j_obj = env->NewGlobalRef(jobj);//**这里是关键**    //jclass clazz = env->GetObjectClass(jobj);//之前是这样写,一直导致奔溃    j_mid = env->GetMethodID(clazz, "recvData", "(Ljava/lang/String;[BII)V");    if(j_mid == NULL)    {        LOGE("Error GetMethodID");    }}jint JNI_OnLoad(JavaVM* vm, void* reserved){    LOG("JNI_OnLoad");    local_JavaVM = vm ;   JNIEnv* env = 0;    jint ret = -1;   if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)    {        LOGE("JNI_OnLoad error");        goto onLoadError;    }    ret = JNI_VERSION_1_6;    onLoadError:    return ret;}

步骤3.我这里的应用p2p在收到视频流数据的时候,需要将视频数据传送到java层,例如其他c文件xxxxx.c收到视频数据,在调用CallVoidMethod可以调用java函数(注意这是c代码)。

extern jmethodID j_mid ;extern jobject j_obj ;extern JavaVM* local_JavaVM;JNIEnv *env;**//这是一个线程**void dataRecvThread(){        int ret = 0;    int status = (*local_JavaVM)->GetEnv(local_JavaVM, (void **)&(env), JNI_VERSION_1_6);    if(status < 0)    {        status = (*local_JavaVM)->AttachCurrentThread(local_JavaVM, &(env), NULL);//**这是关键地方**        if(status < 0)        {            return NULL;        }        ret= 1;    }   ..............//接受视频代码省略   if(j_obj != NULL && j_mid != NULL)    {                            int nDataType = data.frameType;            int nLen = data.len;            jstring jdevid = (*env)->NewStringUTF(env, "ARD1W45LKUYHAAAA1E");            jbyteArray jbuff = (*env)->NewByteArray(env, nLen);            (*env)->CallVoidMethod(env, j_obj , j_mid , jdevid, jbuff, nDataType, nLen);            (*env)->DeleteLocalRef(env, jbuff);            (*env)->DeleteLocalRef(env, jdevid);     }     .............//代码省略    if(ret)    {        (*local_JavaVM)->DetachCurrentThread(local_JavaVM);    }}

这样就可以成功调用了

转载于:https://www.cnblogs.com/zhujiabin/p/10596767.html

你可能感兴趣的文章
Android 5.1 open data flow 数据开启流程
查看>>
HDU 3948 The Number of Palindromes(Manacher+后缀数组)
查看>>
BZOJ1070[SCOI2007]修车
查看>>
练习:利用函数写一个扑克牌列表
查看>>
DRF 视图
查看>>
利用libqrencode生成二维码
查看>>
分布式重复提交
查看>>
Selenium vs TestStudio,Selenium Grid vs F2Test
查看>>
PHP中的错误处理和日志函数
查看>>
mysql 判断两个字符串是否存在包含关系-------(1,2,3)与(2,3)
查看>>
span 超出内容自动换行
查看>>
AJAX
查看>>
python字典
查看>>
python 中如何判断list中是否包含某个元素
查看>>
Python实现XML文件解析
查看>>
fastJson解析复杂的json字符串,经测试已经成功解析
查看>>
LeetCode & Online Programming Learning Platform
查看>>
xml 模块
查看>>
14.7.1 重新调整InnoDB系统表空间的大小
查看>>
存储过程
查看>>