【问题标题】:How to handle lots of messages being sent from android service?如何处理从android服务发送的大量消息?
【发布时间】:2022-01-05 11:59:11
【问题描述】:

我正在开发一个使用 MAVLINK 协议进行通信的应用程序。我为此使用dronefleet。我的应用程序有一个运行ReadThread 的服务,它检查传入的MAVLINK messages 的类型。 ReadThread 然后向 UI 发送消息,以使用无人机的电池状态等信息更新一些 TextViews。这是我的代码。

ReadThreadDService.java

import io.dronefleet.mavlink.MavlinkMessage;
import io.dronefleet.mavlink.common.Attitude;
import io.dronefleet.mavlink.common.SysStatus;

public static final int ATTITUDE = 1;
public static final int SYS_STATUS = 2;

private class ReadThread extends Thread {
        private AtomicBoolean keep = new AtomicBoolean(true);
        @Override
        public void run() {
            while(keep.get()){
                if(inputStream == null)
                    return;
                MavlinkMessage message;
                try {
---------------------get MAVLINK message from stream here---------------
                    message = mavlinkConnection.next();
    
-------------------check MAVLINK message type and then send message to UI for updating related fields--------------------
           
                    if(message.getPayload() instanceof Attitude) {
                        MavlinkMessage<Attitude> attitudeMessage = (MavlinkMessage<Attitude>)message;

                        myHandler.obtainMessage(ATTITUDE, attitudeMessage).sendToTarget();
                    }

----------------removing comments causes app to crash---------------------
                    
/*if(message.getPayload() instanceof SysStatus) {
                        MavlinkMessage<SysStatus> sysStatusMessage = (MavlinkMessage<SysStatus>)message;
                        int battery = sysStatusMessage.getPayload().batteryRemaining();
                        
                        myHandler.obtainMessage(SYS_STATUS, Integer.toString(battery)).sendToTarget();*/
                    }
                    
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        public void setKeep(boolean keep) {
            this.keep.set(keep);
        }
    }

handleMessage() in MainActivity.java

            switch (msg.what) {
                
                case DService.SYS_STATUS:
                    String battery = (String) msg.obj + "%";
                    myActivity.get().batteryView.setText(battery);

                case DService.ATTITUDE:
                    MavlinkMessage<Attitude> message = (MavlinkMessage<Attitude>) msg.obj;
                    String pitch = Float.toString(message.getPayload().pitch());
                    String roll = Float.toString(message.getPayload().roll());
                    String yaw = Float.toString(message.getPayload().yaw());
                    myActivity.get().pitchView.setText(pitch);
                    myActivity.get().rollView.setText(roll);
                    myActivity.get().yawView.setText(yaw);
                    break;
        
            }
        }

我的问题是,如果我在 ReadThread 中检查不止一种类型的 MAVLINK 消息,我的应用程序就会崩溃。如果我检查(比如说)SYS_STATUSATTITUDE,那么 UI 中相应的TextViewss 每秒都会无缝更新(这是 MAVLINK 发送消息的速率)。但不适用于 2 个消息类。如果我从一个 if 块中删除 cmets,我的应用程序将崩溃。

可能是什么原因?我的handleMessage() 错了吗?我需要使用MessageQueue 或其他一些安卓机制吗?我是否应该为每种 MAVLINK 消息类型运行单独的线程,例如 ReadThread

我正在 Ubuntu 18 上开发,并使用 Android Studio。

【问题讨论】:

    标签: java android android-service android-handler mavlink


    【解决方案1】:

    您的程序在崩溃之前是否会抛出任何异常?

    我不会为每个 MAVLink 消息类型的句柄消息使用多个线程,因为我猜测用于 MAVLink 连接的dronefleet 解析器是有状态的(MAVLink 使用魔术前缀和有效负载长度来分隔数据包)并且它可能会中断或被如果从多个线程调用,则几乎是同步的。

    如果您担心自己可能过于频繁地发送更新,您可以让读取线程存储来自不同 MAVLink 消息的值,并由一个单独的线程根据每条消息的最新值以固定间隔发送更新,或者自上次更新以来收到的消息集。

    【讨论】:

      猜你喜欢
      • 2011-12-31
      • 1970-01-01
      • 2021-07-04
      • 2012-06-21
      • 2020-08-06
      • 2014-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多