3

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

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 线程通信?

4

1 回答 1

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 不会立即发生,因此您需要确保下一条消息在处理之前不会覆盖当前消息。

于 2013-08-26T20:07:00.077 回答