1

我正在做一个网络测验,我遇到了处理来自线程的活动的问题。这是我的代码Client,它(成功)连接到服务器:

public class Client extends Thread {
    private MainActivity activity;
    private Socket socket;

    private DataInputStream dataIn;
    private DataOutputStream dataOut;
    private String host;
    private int port;

    public Client(String host, int port, MainActivity activity) {

            this.host = host;
            this.port = port;
            this.activity = activity;

//          At this point of the code, it works just great:
            activity.setQuestion("Question", "A", "B", "C", "D", 1);


            this.start();
    }

    private void processMessage( String msg ) {
        try {
            dataOut.writeUTF(msg);

        } catch (IOException e) {
            System.out.println(e);
        }
    }

    void handleMessage(String msg) {
        if (msg.equals("changeQuestion")) {

//          This does not work:
            activity.setQuestion("Question", "A", "B", "C", "D", 1);
        }
    }



    @Override
    public void run() {
        try {
            socket = new Socket( host, port );
            dataIn = new DataInputStream( socket.getInputStream() );
            dataOut = new DataOutputStream( socket.getOutputStream() );

            while (true) {
                String msg = dataIn.readUTF();
                handleMessage(msg);

            }
        } catch (IOException e) {
            System.out.println(e);
        }   


    }

}

setQuestion(...)方法在 中调用MainActivity,其中问题和答案按钮的标题设置为字符串。正如我的评论告诉你的那样,在线程启动之前它确实有效,但是一旦线程启动,它就会崩溃。

这是我的setQuestion(...)方法,它在于MainActivity

public void setQuestion(String Q, String A, String B, String C, String D, int correctAnswer) {

    TextView tvQuestion = (TextView) findViewById(R.id.tvQuestion);
    tvQuestion.setText("");

    Button btnA = (Button) findViewById(R.id.btnAnswerA);
    Button btnB = (Button) findViewById(R.id.btnAnswerB);
    Button btnC = (Button) findViewById(R.id.btnAnswerC);
    Button btnD = (Button) findViewById(R.id.btnAnswerD);

    tvQuestion.setText(Q);
    btnA.setText(A);
    btnB.setText(B);
    btnC.setText(C);
    btnD.setText(D);

    this.correctAnswer = correctAnswer;
}
4

2 回答 2

0

您的 handleMessage() 是从新线程调用的,而不是主 UI 线程。考虑将 AsyncTask 用于诸如此类的事情。那是干净的方式。

于 2013-11-02T19:21:45.673 回答
0

无法从线程更新 ui。setQuestion从线程中调用,您将文本设置为 setQuestion 中的按钮。

检查线程@下的主题

http://developer.android.com/guide/components/processes-and-threads.html

您可以使用HandlerorAsynctaskrunOnUiThread

activity.runOnUiThread(new Runnable() {
public void run() {
    activity.setQuestion("Question", "A", "B", "C", "D", 1);
 }
}
于 2013-11-02T19:23:36.287 回答