从BufferedReader连接字符串并传递给UI线程

时间:2014-05-02 15:11:29

标签: java android sockets

首先,这是我的第一个Android / Java套接字项目!看看下面的方法。我的目标是从套接字连接接收多行文本(实际上是包装器中的xml)。我试图读取每一行并将其连接到一个字符串,并将其传递回messageReceived方法进行进一步处理。读取和连接工作正常但是代码永远不会执行超出s = mBufferIn.readLine()while循环?如果我在条件测试mServerMessage的值上设置断点,它永远不会得到这么远,即使mServerMessage包含从服务器发送的所有内容。如果我删除while循环并将mServerMessage的值设置为mBufferIn.readLine()的值,则每行都会成功发送到UI线程,但我需要将整个数据包立即发送到messageReceived方法。我该怎么做才能纠正这个问题?

更新

我已经修改了run()方法中的while循环,以根据下面的建议检查消息的结尾。这是正常工作,因为在消息中找到ETX字符时连接停止,但IF条件永远不会执行。这可能与AsyncTask有关吗?我已经发布了位于MainActivity任务中的ConnectTask类,因为这是我连接到套接字的方式。

MainActivity

public class ConnectTask extends AsyncTask<String, String, TcpClient> {

    @Override
    protected TcpClient doInBackground(String... message) {

        mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
            @Override
            //implement the messageReceived method
            public void messageReceived(String message) {
                //this method calls the onProgressUpdate
                publishProgress(message);
            }
        });
        mTcpClient.run();

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        //do something with received message
    }
}

TcpClient类

public void run() {
    mRun = true;
    try {
        InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
        Log.e("TCP Client", "C: Connecting...");
        Socket socket = new Socket(serverAddr, SERVER_PORT);

        try {
            mBufferOut = socket.getOutputStream();
            mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            while (mRun) {
                String s;
                while ((s = mBufferIn.readLine()) != null && s.indexOf(ETX) < 0) {
                   mServerMessage += s;
                }

                if (mServerMessage != null && mMessageListener != null) {
                    //call the method messageReceived from MyActivity class
                    mMessageListener.messageReceived(mServerMessage);
                }
            }

            Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");
        } catch (Exception e) {
            Log.e("TCP", "S: Error", e);
        }

    } catch (Exception e) {
        Log.e("TCP", "C: Error", e);
    }
}

1 个答案:

答案 0 :(得分:1)

您正在设置一个循环,其中停止条件是.readLine()null。这显然不会发生,因为每次从远程服务器读取一行时,它都有一些内容(与null不同),所以你不会离开循环。

有几种方法可以达到你想要的效果:

  • 其中一个将从远程服务器发送“EOF”消息(如果可以的话),例如,发送String这将是“嘿,我已经完成了,现在你必须停止“。然后将循环更改为:

    while (!(s = mBufferIn.readLine().equals("Hey, I'm done and now you have to stop"))) { ... }
    
  • 另一个是按原样离开循环而不是在每一行上追加读取的内容,而是调用一个方法(比如processString(s)),这将启动Thread并发送主要Activity的内容。因此对IntentBroadcastReceiver等有效。这样你就不会阻止循环的其余部分的执行并按原样处理字符串。

    < / LI>