从socket中读取数据,在Android应用程序中冻结UI的问题

时间:2012-06-24 16:15:46

标签: java android

我目前正在开发一个需要从蓝牙插槽读取数据的Android应用程序。我使用的代码如下:

runOnUiThread(new Runnable() {
    public void run()
    {
        try{
            ReadData();
    }catch(Exception ex){}
    }
});
public void ReadData() throws Exception{
    try {
        b1 = new StringBuilder();
        stream = socket.getInputStream();
        int intch;
        String output = null;
        String k2 = null;
        byte[] data = new byte[10];
        // read data from input stream if the end has not been reached
        while ((intch = stream.read()) != -1) {
            byte ch = (byte) intch;
            b1.append(ByteToHexString(ch) +"/");
            k++;
            if(k == 20) // break the loop and display the output
            {
                output = decoder.Decode(b1.toString());
                textView.setText(output);
                k=0;
                break;
            }
        }
        // close the input stream, reader and socket
        if (stream != null) {
            try {stream.close();} catch (Exception e) {}
            stream = null;
        }
        if (socket != null) {
            try {socket.close();} catch (Exception e) {}
            socket = null;
        }
    } catch (Exception e) {
    }
}

然而,当我在Android设备上运行应用程序时,UI不会自动更新并且它会一直冻结。有谁知道如何解决UI冻结问题?我想动态地在UI上显示数据,而不是在完成循环后显示数据。

提前感谢您的任何帮助。

此致

查尔斯

3 个答案:

答案 0 :(得分:1)

InputStream.read() java says上:

  

此方法将阻止输入数据可用

您的UI正在阻止,因为您正在从UI线程上的套接字读取。你应该肯定有另一个线程从套接字读取数据并将结果传递给UI进行动态更新。

答案 1 :(得分:0)

您应该在非UI线程上运行ReadData()方法,然后一旦数据可用,请使用runOnUIthread机制在UI线程上仅运行textView的结果更新。

答案 2 :(得分:0)

试试这个,

工作原理。

1. When Android Application starts you are on the UI Thread. Doing any Process intensive    work on this thread will make your UI unresponsive.

2. Its always advice to keep UI work on UI Thread and Non-UI work on Non-UI Thread. But from HoneyComb version in android it became a law.

您的代码中存在问题。

1. You are reading the data on the UI thread, making it wait to finish reading..    here in this line... while((intch = stream.read())!= -1))。

如何解决问题:

1. Use a separate Non-UI thread, and to put the value back to the UI thread use Handler.

2. Use the Handler class. Handler creates a reference to the thread on which it was created. This will help you put the work done on the Non-UI thread back on the UI thread.

3. Or use AsyncTask provided in android to Synchronize the UI and Non-UI work,which does work in a separate thread and post it on UI.