Android套接字:实时接收数据

时间:2013-08-26 19:48:05

标签: java android sockets

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

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

1 个答案:

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