尝试通过Handler更新TextField,并获取CalledFromWrongThreadException

时间:2010-11-22 01:01:15

标签: android android-widget

我似乎无法从线程更新TextView。我有一个GameConnection类(管理套接字连接),我希望跨活动使用它。它调用本地“onMessage”,然后使用目标处理程序调用dispatch Message。在这种情况下,“处理程序”在我的GameBrowser活动中。

这是来自GameConnection类的代码。

in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);

String message = "".intern();

// as a newline character is read, we interpret it as a message
while ((message = in.readLine()) != null && isConnected){
    onMessage(message);
}

如上所述,本地方法“onMessage”方法处理消息的调度。

  private void onMessage(String message){
       ... // create message from String
      handler.dispatchMessage( msg );
  }

然而,当我在GameBrowser类中得到响应时,我得到一个CalledFromWrongThreadException。最初,我使用的是回调方法,当然这种方法不起作用。因此,经过一些研究,我发现我必须使用Handler,但我似乎无法正确使用。

public class GameBrowser extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    Log.d(C.tag, "GameBrowser.onCreate addr:" + this);

    handler = new Handler(new HandlerCallback());

    connection.addMessageListener(handler);
    connection.connect();
    txtGameLabel = (TextView)findViewById( R.id.txtGamesLabel);
    setContentView(R.layout.game_browser);


}

private class HandlerCallback implements Callback{

    @Override
    public boolean handleMessage(Message msg) {

        if (txtGameLabel == null){
            txtGameLabel =  (TextView)findViewById( R.id.txtGamesLabel);
        }

        String message = msg.getData().getString("message");

        Log.d(C.tag, "GameBrowser recieved message " + message);

        txtGameLabel.setText("Data: " + message);

        return true;
    }
}

}

1 个答案:

答案 0 :(得分:0)

我弄清楚我做错了什么。我没有使用套接字线程调用处理程序,而是使用了一个回调,然后使用Runnable发布到GameConnection类中的处理程序。当onMessage执行“run”,执行“updateTextField”时,我们回到主线程中。

@Override
public void onMessage(final String message) {

    handler.post(new Runnable(){
        @Override
        public void run() {
            updateTextField(message);

        }
    });

}

private void updateTextField(String message){
    if (txtGameLabel == null)
        txtGameLabel = (TextView)findViewById( R.id.txtGamesLabel);

    txtGameLabel.setText(message);
}