JNI层消息交互的注意事项

在一款车载检测产品的开发中,通过JNI层进行手机应用与车机设备的通信。在测试阶段发现数据接收失败的问题,排查后确定问题集中在JNI层。主要问题包括:1) 消息队列中消息获取不完整,由于删除消息的时机不当导致;2) 应用层获取到的是旧数据,原因是消息队列作为共享资源未加锁。解决办法是调整消息删除时机和引入锁机制确保线程安全。
摘要由CSDN通过智能技术生成

这段时间负责公司一款车载检测产品的平台开发和维护工作。这款产品的工作模式是通过手机端的应用与插在车上的车机设备通信,来实现一些功能。手机端代码实现上是将公司的C代码的应用移植到手机应用上,以动态链接库的方式,通过JNI层与java层交互。

产品研发和测试已经接近尾声,但是应用在测试中还是发现存在极个别的情况下接收数据失败的问题。通过几天的查找,已经完全排除了接头端的问题,也排除了C应用端的问题,那么主要问题就可能出在JNI层了,通过在jni层中加log,发现确实是存在问题,具体问题如下:

1、java通过jni层存储到消息队列中的消息,应用层通过jni层获取不到或获取不完整,一般是掉了最后一帧。

查找一圈,发现问题的根本如下: 

//之前的代码

void QUEUE_MSG::getSendMsg(MSGDLLTOEXE *msg) {
    if (send_msg.msg.empty()) {
        //重置返回一个无效消息
        msg->msgtype = 0;
        msg->action_tp = 0;
        msg->ui_act = 0;
        msg->db_act = 0;
        msg->cal_act = 0;
        msg->cmd_rlen = 0;
    } else {
        *msg = send_msg.msg.front();  //获取消息队列中最前面的消息
        send_msg.msg.pop();          // 删除消息队列中最前面的消息
    }

  我的理解是:这种将队列顶部的消息取出之后再删除队列中消息的操作,一般是没有什么问题的,但是如果消息队列中的指针变量指向了一块数据区域,在pop()的动作做出之后,连带着对已取出的消息造成的影响。导致已取出的消息是空消息,后续将代码修改如下之后,问题得到解决:

//之后的代码
void QUEUE_MSG::getReceiveMsg(MSGDLLTOEXE *msg) {

    if(msg->msgtype == 300) {

        while(receive_msg_cmd_lock == 1)
        {
            Delay(1);
        }
        receive_msg_cmd_lock 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值