Android处理程序:发送8条不同的消息:处理程序找到8条消息但只使用了最后一条消息

时间:2013-08-16 14:47:06

标签: android view handler message

我是Android新手,发现为了不断更新主视图,我必须创建一个线程来处理各种进程,然后将更新传递给主视图。我决定使用Handler类来执行此操作。此示例中的视图有一个用于激活代码的按钮和一个用于显示接收消息的tablelayout - 表示该过程的一个阶段。

问题是我发送了8条不同的消息,我可以在处理程序中看到8条消息,但是所有8条消息都只有消息8的内容。

我期待处理程序按顺序选择消息。

任何有关更好的方法的建议总是值得学习。

以下是代码:

`

public class messageHandlerTest extends Activity {

protected TextView textView;
protected Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String[] status = (String[]) msg.obj;
            createTableRow(status);
            Log.e("Got a new message",status[0]+":"+status[1]);
        }
    };

Button btnStartProgress;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textView = (TextView) findViewById(R.id.statusText);
    textView.setText("");
    //Getting response from server with Network SSID and Password

    Button connectButton = (Button)findViewById(R.id.connectButton);
    addListenerOnButton();
} // End of create

protected class connectWiFi extends Thread implements Runnable {
    //tokens1 = new String[0];
    public void run(){
    try {
        String[] messageString = new String[2];
        Message message = handler.obtainMessage();
        messageString[0]="OK";
        messageString[1]="Number 1";
        message.obj = messageString;
        handler.sendMessage(message);

        message = handler.obtainMessage();
        messageString[0]="OK";
        messageString[1]= "Number 2";
        message.obj = messageString;
        handler.sendMessage(message);
        message = handler.obtainMessage();
        messageString[0]="OK";
        messageString[1] = "Number 3";
        message.obj = messageString;
        handler.sendMessage(message);
        message = handler.obtainMessage();
        messageString[0]="OK";
        messageString[1] = "Number 4";
        message.obj = messageString;
        handler.sendMessage(message);

                    message = handler.obtainMessage();
                    messageString[0] = "OK";
                    messageString[1] = "Number 5";
                    message.obj = messageString;
                    handler.sendMessage(message);

                    message = handler.obtainMessage();
                    messageString[0] = "OK";
                    messageString[1] = "Number 6";
                    message.obj = messageString;
                    handler.sendMessage(message);

                    message = handler.obtainMessage();
                    messageString[0] = "OK";
                    messageString[1] = "Number 7";
                    message.obj = messageString;
                    handler.sendMessage(message);

                    message = handler.obtainMessage();
                    messageString[0] = "OK";
                    messageString[1] = "Number 8";
                    message.obj = messageString;
                    handler.sendMessage(message);

    } catch (Exception e) {
        e.printStackTrace();
        Log.e("Exception found","bugger");
    }
    }// End or run
}// End of class

public void addListenerOnButton() {

    btnStartProgress = (Button) findViewById(R.id.connectButton);
    btnStartProgress.setOnClickListener(
            new OnClickListener() {
                @Override
                public void onClick(View v) {
                connectWiFi connectwifi = new connectWiFi();
                connectwifi.start();
                }

            });

}
private void createTableRow(String[] stage) {
    TableLayout tl = (TableLayout) findViewById(R.id.statusTable);
    TableRow tr = new TableRow(this);
    LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    tr.setLayoutParams(lp);
    tr.setBackgroundColor(0xFFFFFFFF);
    TextView tvStatus = new TextView(this);
    tvStatus.setLayoutParams(lp);
    tvStatus.setPadding(2,1,1,2);
    tvStatus.setTextColor(0xFF000000);
    tvStatus.setText(stage[0]); // Status
    TextView tvStage = new TextView(this);
    tvStage.setLayoutParams(lp);
    tvStage.setPadding(2,1,1,2);
    tvStage.setTextColor(0xFF000000);
    tvStage.setText(stage[1]); // Stage
    tr.addView(tvStatus);
    tr.addView(tvStage);
    tl.addView(tr, new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
}
@Override
protected void onDestroy() {
    super.onDestroy();
}

}

此代码的结果如下:

enter image description here

5 个答案:

答案 0 :(得分:8)

要通过处理程序发送数据,您可以使用bundle作为要发送给处理程序的消息对象的数据。喜欢这段代码:

// receieve message in handleMessage method of handler of your controller (e.g. on UI thread)
handler = new Handler() { 
    @Override
    public void handleMessage(Message msg) {
        Bundle b = msg.getData();
        Integer value = b.getInt("KEY");
        ...
    }
};

// Sending message in a background thread
new Thread(new Runnable() {
    @Override
    public void run() {
        final Message msg = new Message();
        final Bundle b = new Bundle();
        Integer value = 1;
        b.putInt("KEY", value);
        msg.setData(b);
        handler.sendMessage(msg);    
    }
).start();

答案 1 :(得分:3)

我怀疑可能发生的事情是你不断修改名为messageString的同一个引用String [],而从不创建一个新的。通过引用传递然后继续更改值可能会导致此结果。

一些事情,

  1. 使用处理程序时,请尝试使用what字段作为返回代码。对于instnace,你的OK字符串(如果它只是一个状态)你最好定义int常量返回类型。
  2. 正如JanBo所提到的,你不想扩展Thread并实现Runnable。
  3. 这实际上取决于您正在尝试做什么,但Handler消息队列回调模式是您可以选择实现所需内容的众多模式之一。为了学习另一种方法,请查看我撰写的here博客文章,其中介绍了如何将非UI线程任务委派给IntentService,并在完成后回调您的Activity。

答案 2 :(得分:2)

我想发生的事情是:messageString,只创建一次,在message等待队列时正在更新。像这样更改你的代码:

String[] messageString1 = new String[2];
Message message = handler.obtainMessage();
messageString1[0]="OK";
messageString1[1]="Number 1";
message.obj = messageString1;
handler.sendMessage(message);

String[] messageString2 = new String[2];
message = handler.obtainMessage();
messageString2[0]="OK";
messageString2[1]= "Number 2";
message.obj = messageString2;
handler.sendMessage(message);

....
....

答案 3 :(得分:1)

我不确定我是否在正确的位置做这个,但我想我会根据我在这里收到的帮助回发我的重构代码,这可能对其他人有所帮助。这对我来说效果很好,而且代码看起来非常整洁,但是对于如何改进或提高效率的任何反馈都将不胜感激。如果我在错误的地方这样做,请告诉我!

public class messageHandlerTest2 extends Activity {

protected TextView textView;
protected Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        createTableRow((mymessageObject) msg.obj);
    }
};  //Set-up handler to be used later

Button btnStartProgress;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button connectButton = (Button) findViewById(R.id.connectButton);
    addListenerOnButton();
} // End of create

protected class connectWiFi extends Thread {
    public void run() {
        try {
            sendMessage(true,"Number 1"); // send if OK and a stage message
            sendMessage(true,"Number 2");
            sendMessage(true,"Number 3");
            sendMessage(true,"Number 4");
            sendMessage(true,"Number 5");
            sendMessage(true,"Number 6");
            sendMessage(true,"Number 7");
            sendMessage(true,"Number 8");
            sendMessage(true,"Number 9");
            sendMessage(true,"Number 10");
            sendMessage(true,"Number 11");
            sendMessage(true,"Number 12");

        } catch (Exception e) {
            e.printStackTrace();
            Log.e("Exception found", "bugger");
        }
    }// End or run
}// End of class

public void addListenerOnButton() {

    btnStartProgress = (Button) findViewById(R.id.connectButton);
    btnStartProgress.setOnClickListener(
            new OnClickListener() {
                @Override
                public void onClick(View v) {
                    connectWiFi connectwifi = new connectWiFi();
                    connectwifi.start();
                }

            });
}

private void createTableRow(mymessageObject stage) {
    String statusString;
    TableLayout tl = (TableLayout) findViewById(R.id.statusTable);
    TableRow tr = new TableRow(this);
    LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    tr.setLayoutParams(lp);
    tr.setBackgroundColor(0xFFFFFFFF);
    TextView tvStatus = new TextView(this);
    tvStatus.setLayoutParams(lp);
    tvStatus.setPadding(2, 1, 1, 2);
    tvStatus.setTextColor(0xFF000000);
    if (stage.Status) {statusString = "OK";} else {statusString = "No";};
    tvStatus.setText(statusString); // Status
    TextView tvStage = new TextView(this);
    tvStage.setLayoutParams(lp);
    tvStage.setPadding(2, 1, 1, 2);
    tvStage.setTextColor(0xFF000000);
    tvStage.setText(stage.statusMessage); // Stage
    tr.addView(tvStatus);
    tr.addView(tvStage);
    tl.addView(tr, new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
}

@Override
protected void onDestroy() {
    super.onDestroy();
}
private class mymessageObject {  // Creates object of status flag and stage message
    boolean Status;
    String statusMessage;
    mymessageObject(boolean newStatus, String newMessage){
        Status = newStatus;
        statusMessage = newMessage;
    }
}
private void sendMessage (boolean status, String stageMessage) { // Handle sending message back to handler

    Message message = handler.obtainMessage();
    message.obj = new mymessageObject(status,stageMessage);
    handler.sendMessage(message);
}

}

答案 4 :(得分:-3)

试试这个

Message m = Message.obtainMessage();

不是

Message m = handler.obtainMessage();