我正在编写一个客户端 - 服务器应用程序来测试两个Android蓝牙设备之间的通信。在我的客户端,我正在读取inputstream对象的数据。 当我通过在logcat上打印进行检查时,数据正在被成功读取。但是,当我尝试将数据设置为TextView时,它不会显示。
在以下代码中,packetsReceivedTV是TextView对象。我在logcat上打印'result'时输出正确,但文本未在TextView中设置。是因为我在一段时间(监听)循环中设置文本吗?
while(listening){
bytesRead =instream.read(buffer);
if(bytesRead!=-1){
String dataRead= new String(buffer,"UTF-8");
System.err.println("*************result : "+dataRead);
packetsReceivedTV.setText("Received : "+dataRead);
packetsReceivedTV.invalidate();
}
}
即使调用invalidate()也无效。
注意:有时,当我在一台设备上终止服务器进程时,客户端设备上的TextView会正确更新。但这并不总是发生。请帮忙!
答案 0 :(得分:1)
我们不清楚您的代码被调用到哪个线程,但您需要确保这两个操作发生在不同的线程上:
read()
上的线程阻塞使主线程不会更新UI元素。setText()
方法调用必须在主(UI)线程上进行。如果你不这样做,文本也不会显示 - 在某些设备上你甚至会看到崩溃。我假设此代码存在于一个活动中(因为您正在尝试更新UI元素)。 虽然这不是最佳做法 ,但演示此概念的简单示例如下:
Thread pollingThread = new Thread() {
@Override
public void run() {
…
//This code needs to be running on a background thread
while(listening){
bytesRead = instream.read(buffer);
if(bytesRead != -1){
String dataRead= new String(buffer,"UTF-8");
System.err.println("*************result : "+dataRead);
runOnUiThread(new Runnable() {
@Override
public void run() {
//This code needs to be posted back to the main thread.
packetsReceivedTV.setText("Received : "+dataRead);
}
});
}
}
}
};
//Start the listener thread
pollingThread.start();
这实际上只是为了说明轮询代码 必须 在后台并且视图代码 必须 在主线上。
即使调用invalidate()也无效。
TextView
在内容发生变化时会在内部调用,因此您调用它是多余的。