【问题标题】:Android sockets: receiving data in real-timeAndroid sockets:实时接收数据
【发布时间】:2013-08-26 19:48:04
【问题描述】:

我有另一个设备和应用程序实时传输数据(每隔几毫秒),在我的接收设备上,我想:

1) 读取/接收此数据,并且 2) 使用它来更新 UI 元素(在本例中为动态图)

数据发送方在后台服务中使用套接字,每隔几毫秒使用 AsyncTasks 发送数据。要初始化,它会执行以下操作:

echoSocket = new Socket(HOST, PORT);
out = new PrintWriter(echoSocket.getOutputStream(), true);

并且它会定期发送数据:

static class sendDataTask extends AsyncTask<Float, Void, Void> {

        @Override
        protected Void doInBackground(Float... params) {
            try { 
                JSONObject j = new JSONObject();
                j.put("x", params[0]);
                j.put("y", params[1]);
                j.put("z", params[2]);
                String jString = j.toString();
                out.println(jString);
            } catch (Exception e) {
                Log.e("sendDataTask", e.toString());
            }
            return null;
        }

    }

我应该如何在我的应用程序中接收这些数据?我是否还应该使用带有 AsyncTasks 的后台服务来尝试每隔几毫秒从套接字读取一次?如何与 UI 线程通信?

【问题讨论】:

    标签: java android sockets


    【解决方案1】:

    有很多方法可以做到这一点。最简单的方法是在 AsyncTask 的 doInBackground 方法中使用阻塞读取并调用 publishProgress() 将新数据转发到 UI 线程。

    然后使用更新屏幕的代码(在 UI 线程中运行)实现 onProgressUpdate。

    您应该知道,您的读取可能不会收到您发送的整个消息 - 您可能需要读取更多数据并将其附加到目前收到的输入中,直到您收到完整的 JSON 消息。

    通过阻止读取,我的意思是这样的(在伪代码中):

    open a socket connected to the sender
    is = socket.getInputStream()
    initialize buffer, offset, and length
    while the socket is good
        bytesRead = is.read(buffer, offset, length)
        if(bytesRead <= 0)
            bail out you have an error
        offset += bytesRead;
        length -= bytesRead 
        if(you have a complete message)
            copy the message out of the buffer (or parse the message here into
              some other data structure)
            publishProgress(the message)
            reset buffer offset and length for the next message.
             (remember you may have received part of the following message)
        end-if
    end-while
    

    缓冲区复制是必要的,因为 onProgressUpdate 不会立即发生,因此您需要确保下一条消息在处理之前不会覆盖当前消息。

    【讨论】:

    • 在代码中概念化这个有点麻烦。 while the socket is good - 这应该在 AsyncTask 的 doInBackground 中吗?那么它只是保持运行并调用publishProgress 每隔几毫秒更新一次 UI 线程?
    • 是的。它会在读取时进入休眠状态,等待数据到达并仅在实际进入时发布数据。
    • 如果您与许多设备通信,这种技术不能很好地扩展,但对于单个连接,它是最好/最简单的方法。
    • 好的,谢谢,对我来说似乎是一个很好的起点。作为参考,如何从多个设备读取实时套接字?像 10 一样,尽可能快地转储数据……
    • 看看 Reactor 设计模式。在 C++ 中,它被 ACE 和 Boost ASIO 使用。我不熟悉该模式的 Java 实现,但我认为存在一个,因为它是一个常见问题。您还可以看看 DDS(数据分发系统),它专为此类问题(更大规模)而设计
    猜你喜欢
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 2014-07-08
    • 1970-01-01
    相关资源
    最近更新 更多