android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题

最近在移植网络摄像机里的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);
    }
}

这样就可以成功调用了

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值