JNI C 语言中开启线程调用Java中方法

这篇博客介绍了如何在Android的JNI环境中,使用C语言开启新线程并调用Java方法。关键点在于理解JNIEnv *env的线程局部性,以及如何通过JavaVM获取当前线程的JNIEnv实例。文章详细展示了从定义Java接口、实现监听,到C++中初始化JNIEnv,以及最终调用Java方法的过程。
摘要由CSDN通过智能技术生成

Android 开发菜鸟,请大家多多指教!

  1、 在C中直接调用与开启线程调用java方法是有所不同,这是由JNIEnv *env的使用限制引起的

     JNIEnv *env是一个结构体指针它指向JNI函数表,通过它能调用JNI所有函数来使用虚拟机的各种功能,例如;查找某个类(验证是否被VM加载、创建各种基本类数组、调用java方法等,它的方法几乎都是很有的),它是一个指向线程的局部数据,不能被保存来供其它线程使用(方法调用的相关线程中也有效),它与线程是一一对应对应关系(不同的线程有不同的*env,JVM(Dalvik)是一个多线程执行绪,*env中的各种方法归根结底就是通过VM操纵Java线程中的数据,因此,避免造成资源冲突,VM(Dalvik)会给每个方法都传递一个属于当前线程的*env指针)。

    通过VM指针每个线程都可以获取一个属于自己所在线程的JNIEnv *env,在任何线程中可以通过一个全局VM指针访问AttachCurrentThread(JNIEnv** p_env, void* thr_args)或GetEnv(void** env, jint version)方法获取自己的JNIEnv *env,而前者是用于应对该线程是在C中产生在VM中的情况,代码注释中有介绍。

   如何在C中获取VM指针?方法有很多,最常见的方式是在任意一个C组件中(但整个.so中有且只有一该方法)实现一个叫做JNI_OnLoad的方法,代码如下:

JavaVM* gs_jvm;

//当加载.so库时该方法会被VM自动调用,每个*.so库只能有一个这个入口,即使没有定义的也会有一个默认的方法,
jint JNI_OnLoad(JavaVM* vm, void* reserved){
    gs_jvm=vm;//获取一个全局的VM指针
    //TODO 如果想进一步提高JVM访问c中方法的效率可以在这里将C中定义的方法注册到JVM中 (使用JNIHelp.cpp中方法)
    return JNI_VERSION_1_4;
}

但,在本文中同时还需要保存一个Java对象供C中全局操纵,为了方便使用了另一种方法,具体实现在下面代码中有。

 

功能需求:在开发IM的一个APP中,接收消息与发送都是在C中实现,要求APP随时能接收到C层发送消息(json格式的String)。

具体实现:使用一个java单例接收来自C线程发送的消息,然后再解析与分发消息;

java代码:

1、定义消息监听接口:

 
  1. package com.xx.xx.message.listener;
  2.  
  3. public interface OnMessageArriveListener {
  4.     void onMessageArrive(String message);
  5. }​

 

2、实现消息监听接口

 
  1. package com.xx.xx.message.receive;
  2. import android.util.Log;
  3. import com.xx.xx.message.listener.OnMessageArriveListener;
  4.  
  5. /**
  6.  * Created by admin on 2018/6/6.
  7.  */
  8. public class ReceiveMessageImpl implements ReceiveMessage {
  9.     private static final String TAG 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值