这是一个常见的问题,我已经阅读了处理它的各种方法,但似乎每种方法都达不到我想要做的事情,这本质上是一个好的 OO-Citizen。
我有一个调用 CommunicationManager 的 Activity,它基本上轮询 TCP 套接字以获取数据。当 CommunicationManager 接收到数据时,它会抛出一个自定义事件(包含它刚刚获取的字符串),该事件由 Activity 处理。我这样做,A)因为其他类将依赖于该数据,而不仅仅是 Activity,并且 B)因为轮询是异步的,并且应该在收到结果时触发一个事件。
我的问题在于我需要将这些结果显示在 UI 上的 TextView 中。我已经设置了轮询机制,它每 1000 毫秒触发一次,并调用 Activity 上的事件处理程序。但是,UI 永远不会更新。
假设这是一个线程问题,并且 UI 线程不是对 TextView 进行更改的线程,但是我该怎么做呢?我曾尝试使用处理程序,但不确定将它放在哪里,当我得到它编译时,它从未更新过 UI。
如果一切都在 Activity 中完成,这似乎相对微不足道,但是添加另一个类 (CommunicationManager) 和事件让我非常困惑。
这是我到目前为止所拥有的:
活动(通过单击 UI 上的按钮调用轮询):
public void onClick(View v) {
if (v.getId() == R.id.testUDPBtn) {
statusText.setText("");
commMgr = new CommunicationManager();
commMgr.addEventListener(this);
MediaPositionPollThread poller = new MediaPositionPollThread(commMgr);
poller.startPolling();
}
}
@Override
public void handleMediaPositionFoundEvent(MediaPositionFoundEvent e) {
statusText.append(e.userData);
}
线:
class MediaPositionPollThread extends Thread {
private CommunicationManager commManager;
private static final String TAG = "MediaPositionPollThread";
private boolean isPolling = false;
public MediaPositionPollThread(CommunicationManager cm) {
commManager = cm;
}
public void startPolling() {
isPolling = true;
this.run();
}
public void stopPolling() {
isPolling = false;
}
@Override
public void run() {
while (isPolling) {
try {
commManager.getCurrentMediaPosition();
Thread.sleep(1000);
}
catch (InterruptedException e) {
Log.d(TAG, "EXCEPTION: " + e.getMessage());
}
}
}
}
通讯经理:
public void getCurrentMediaPosition() {
PrintWriter outStream;
BufferedReader inStream;
String resultString = "";
try {
outStream = new PrintWriter(tcpSocket.getOutputStream(), true);
outStream.println("GET?current_pts");
inStream = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));
resultString = inStream.readLine();
fireEventWithData(resultString);
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void addEventListener(MediaPositionFoundEventListener listener) {
_listeners.add(listener);
}
public synchronized void removeEventListener(MediaPositionFoundEventListener listener) {
_listeners.remove(listener);
}
private synchronized void fireEventWithData(String outputString) {
MediaPositionFoundEvent evt = new MediaPositionFoundEvent(this);
evt.userData = outputString;
Iterator<MediaPositionFoundEventListener> i = _listeners.iterator();
while(i.hasNext()) {
((MediaPositionFoundEventListener) i.next()).handleMediaPositionFoundEvent(evt);
}
}
因此,我让 Activity 创建一个每秒执行一次的线程,调用 CommunicationManager >> getCurrentMediaPosition,然后触发 MediaPositionFoundEvent,该事件由 Activity 处理并更新屏幕上的 TextView (statusText)。
一切正常,除了屏幕不更新。我已经尝试过 runOnUiThread 和 Handler,但显然没有做对。
提前感谢您提供任何见解或解决方案!