最近在移植网络摄像机里的p2p库到android平台,需要用到jni,最近在c线程了调用java函数的时候
出现一个问题,假如在同一个线程调用java函数是没问题的,但在一个c线程了调用java函数就出现奔
溃问题,下面就直接贴c线程里调用java函数的流程代码吧:

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

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

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

  1. JavaVM* local_JavaVM = NULL;
  2. jobject j_obj = NULL;
  3. jmethodID j_mid = NULL;
  4. JNIEXPORT void JNICALL Java_com_p2p_test_MainActivity_InitP2P (JNIEnv *env, jobject jobj) {
  5. jclass clazz = env->GetObjectClass(jobj);
  6. j_obj = env->NewGlobalRef(jobj);//**这里是关键**
  7. //jclass clazz = env->GetObjectClass(jobj);//之前是这样写,一直导致奔溃
  8. j_mid = env->GetMethodID(clazz, "recvData", "(Ljava/lang/String;[BII)V");
  9. if(j_mid == NULL)
  10. {
  11. LOGE("Error GetMethodID");
  12. }
  13. }
  14.  
  15. jint JNI_OnLoad(JavaVM* vm, void* reserved)
  16. {
  17. LOG("JNI_OnLoad");
  18. local_JavaVM = vm ;
  19.  
  20. JNIEnv* env = ;
  21. jint ret = -;
  22.  
  23. if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
  24. {
  25. LOGE("JNI_OnLoad error");
  26. goto onLoadError;
  27. }
  28.  
  29. ret = JNI_VERSION_1_6;
  30.  
  31. onLoadError:
  32. return ret;
  33. }

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

  1. extern jmethodID j_mid ;
  2. extern jobject j_obj ;
  3. extern JavaVM* local_JavaVM;
  4. JNIEnv *env;
  5. **//这是一个线程**
  6. void dataRecvThread()
  7. {
  8. int ret = ;
  9. int status = (*local_JavaVM)->GetEnv(local_JavaVM, (void **)&(env), JNI_VERSION_1_6);
  10. if(status < )
  11. {
  12. status = (*local_JavaVM)->AttachCurrentThread(local_JavaVM, &(env), NULL);//**这是关键地方**
  13. if(status < )
  14. {
  15. return NULL;
  16. }
  17. ret= ;
  18. }
  19.  
  20. ..............//接受视频代码省略
  21. if(j_obj != NULL && j_mid != NULL)
  22. {
  23. int nDataType = data.frameType;
  24. int nLen = data.len;
  25. jstring jdevid = (*env)->NewStringUTF(env, "ARD1W45LKUYHAAAA1E");
  26. jbyteArray jbuff = (*env)->NewByteArray(env, nLen);
  27. (*env)->CallVoidMethod(env, j_obj , j_mid , jdevid, jbuff, nDataType, nLen);
  28. (*env)->DeleteLocalRef(env, jbuff);
  29. (*env)->DeleteLocalRef(env, jdevid);
  30. }
  31. .............//代码省略
  32.  
  33. if(ret)
  34. {
  35. (*local_JavaVM)->DetachCurrentThread(local_JavaVM);
  36. }
  37. }

这样就可以成功调用了

Android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题的更多相关文章

  1. Android JNI入门第六篇——C调用Java

    本篇将介绍在JNI编程中C调用Java实现. 源码下载地址:http://download.csdn.net/detail/xyz_lmn/4868265 关键代码: java: public cla ...

  2. Android JNI开发之C/C++层调用JAVA

    一.从C/C++层调用JAVA层代码(无参数调用) //在c代码里面调用java代码里面的方法 // java 反射 // 1 . 找到java代码的 class文件 // jclass (*Find ...

  3. LoadRunner调用java函数测试oracle

    LoadRunner调用java函数测试oracle 测试oracle的方法有很多,可以使用loadrunner的oracle协议直接调用oracle进行测试,也可以调用开发的java程序对oracl ...

  4. 基于 Android NDK 的学习之旅----- C调用Java

    许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态 ...

  5. Android NDK 学习之调用Java函数

    本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...

  6. Android jni/ndk编程三:native访问java

    一.访问静态字段 Java层的field和method,不管它是public,还是package.private和protected,从 JNI都可以访问到,Java面向语言的封装性不见了. 静态字段 ...

  7. Android NDK 学习之在C中调用Java的变量和静态变量

    本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...

  8. JS调用Java函数--DWR框架

    (1)dwr与ssh框架整合教程dwr框架介绍. DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJA ...

  9. 在NDK C++线程中如何调用JAVA API

    from://http://www.eoeandroid.com/thread-150995-1-1.html 在NDK中创建的线程中, 只允许调用静态的Java API. 当在线程中调用env-&g ...

随机推荐

  1. Spring boot 配置文件参数映射到配置类属性

    [参考文章]:SpringBoot之@EnableConfigurationProperties分析 [参考文章]:在Spring Boot中使用 @ConfigurationProperties 注 ...

  2. Windows.UI.Cred.dll损坏导致不能设置 PIN 密码

    心血来潮,重装系统. 然后发现不能设置 PIN,UWP界面在输完两个PIN后直接卡死(第一次设置的时候不需要输入第一行的PIN) google无果,打开系统日志,发现 上网下载一个对应版本的Windo ...

  3. SQL Server性能优化(9)聚集索引的存储结构

    一.索引的概念和分类 索引的概念大家都知道,日常开发中我们也会使用常见的聚集索引.非聚集索引.但是除了这两者以外,sqlserver中还提供其他的索引,如: a. 唯一索引:不包含重复键的索引,聚集索 ...

  4. salesforce lightning零基础学习(七) 列表展示数据时两种自定义编辑页面

    上一篇Lightning内容描述的是LDS,通过LDS可以很方便的实例化一个对象的数据信息.当我们通过列表展示数据需要编辑时,我们常使用两种方式去处理编辑页面:Pop Up Window弹出修改详情以 ...

  5. Turbine——Hystrix集群监控

    上一篇文章讲述了如何利用Hystrix Dashboard去监控断路器的Hystrix command.当我们有很多个服务的时候,这就需要聚合所有服务的Hystrix Dashboard的数据了.这就 ...

  6. leetcode — median-of-two-sorted-arrays

    import java.util.HashSet; import java.util.Set; /** * Source : https://oj.leetcode.com/problems/long ...

  7. 设计模式教程(Design Patterns Tutorial)笔记之二 结构型模式(Structural Patterns)

    目录 · Decorator · What is the Decorator Design Pattern? · Sample Code · Adapter · What is the Adapter ...

  8. JavaScript跨域解决方式

    平时工作中经常被JavaScript跨域问题所困扰,其实有很多种解决方式,下面给大家介绍常用的几种: 1.jsonp解决跨域问题 客户端代码: <!DOCTYPE html> <ht ...

  9. [HAOI 2015]按位或

    Description 题库链接 刚开始你有一个数字 \(0\) ,每一秒钟你会随机选择一个 \([0,2^n-1]\) 的数字,与你手上的数字进行或( \(\text{or}\) )操作.选择数字 ...

  10. stark组件之多级过滤

    一.引子 在我们浏览很多页面时,会发现一般情况下都有一个分类的功能,而且还是多个类别同时控制,这就是多级过滤.如下图: 一行代表一个类别,第一行就是展示了所有的出版社,选中后就会以出版社分类,第二行就 ...