2010-11-22 1 views
0

スレッドからTextViewを更新することに問題があるようです。私はGameConnectionクラス(ソケット接続を管理する)を持っています。これは複数のアクティビティで使いたいものです。ローカルの "onMessage"を呼び出し、ターゲットハンドラを使用してディスパッチメッセージを呼び出します。この場合の「ハンドラ」は、私のGameBrowserアクティビティにあります。ハンドラを介してTextFieldを更新しようとしていて、CalledFromWrongThreadExceptionを取得しようとしています

ここに、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が発生します。当初はコールバックメソッドを使用していましたが、もちろんそれは動作しませんでした。だから、いくつかの研究の後で、私はハンドラを使用しなければならないことがわかったが、それを正しく理解することはできない。

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; 
    } 
} 

} 

答えて

0

私が間違っていたことを理解しました。ソケットスレッドからハンドラを呼び出す代わりに、コールバックを使用して、Runnableを使用してGameConnectionクラスのハンドラにポストしました。 onMessageが "updateTextField"を実行する "run"を実行すると、メインスレッドに戻ります。

@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); 
} 
関連する問題