0

这是一个常见的问题,我已经阅读了处理它的各种方法,但似乎每种方法都达不到我想要做的事情,这本质上是一个好的 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,但显然没有做对。

提前感谢您提供任何见解或解决方案!

4

2 回答 2

2

In your Activity class, add a private Handler _handler, Initialize it in your onCreate Activity method,

and change your handleMediaPositionFoundEvent method to

@Override    public void handleMediaPositionFoundEvent(MediaPositionFoundEvent e) {  
          _handler.post(new Runnable(){  
             public void run(){  
               statusText.append(e.userData);  
           });  
          }  
        }
于 2012-06-06T21:41:58.063 回答
1

看起来你用你的 custom 阻塞了 UI 线程Thread。请更新此方法以调用start()vs run()

public void startPolling() {
    isPolling = true;
    this.start();
}
于 2012-06-06T21:52:47.003 回答