上一節中,是主線程自己發了一個消息到自己的Message Queue中,并把消息從隊列中提取出來。那麼如何由别的線程發送消息給主線程的Message Queue中呢?
<span style="font-size: 14px">/**
* MessageQueue2.java
* com.test
*
* Function: TODO
* ver date author
* ──────────────────────────────────
* 2011-3-20 Leon
* Copyright (c) 2011, TNT All Rights Reserved.
*/
package com.test;
/**
* ClassName:MessageQueue2
* Function: TODO ADD FUNCTION
* Reason: TODO ADD REASON
* @author Leon
* @version
* @since Ver 1.1
* @Date 2011-3-20
*/
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MessageQueue2 extends Activity implements OnClickListener {
private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private final int FP = LinearLayout.LayoutParams.FILL_PARENT;
public TextView tv;
private myThread t;
private Button btn, btn2, btn3;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn = new Button(this);
btn.setId(101);
btn.setText("test looper");
btn.setOnClickListener(this);
LinearLayout.LayoutParams param =
new LinearLayout.LayoutParams(100,50);
param.topMargin = 10;
layout.addView(btn, param);
btn2 = new Button(this);
btn2.setId(102);
btn2.setText("exit");
btn2.setOnClickListener(this);
layout.addView(btn2, param);
tv = new TextView(this);
tv.setTextColor(Color.WHITE);
tv.setText("");
LinearLayout.LayoutParams param2 =
new LinearLayout.LayoutParams(FP, WC);
param2.topMargin = 10;
layout.addView(tv, param2);
setContentView(layout);
}
public void onClick(View v) {
switch(v.getId()){
case 101:
t = new myThread();
t.start();
break;
case 102:
finish();
break;
}
}
//------------------------------------------------------
class EHandler extends Handler {
public EHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
tv.setText((String)msg.obj);
class myThread extends Thread{
private EHandler mHandler;
public void run() {
Looper myLooper, mainLooper;
//取出本線程中的Looper,當然如果本句話放在主線程中,則會取得主線程的Looper
myLooper = Looper.myLooper();
//取出主線程中的Looper
mainLooper = Looper.getMainLooper();
String obj;
if(myLooper == null){
mHandler = new EHandler(mainLooper);
obj = "current thread has no looper,this message is from Main thread!";
}
else {
mHandler = new EHandler(myLooper);
obj = "This is from new thread.";
mHandler.removeMessages(0);
Message m = mHandler.obtainMessage(1, 1, 1, obj);
mHandler.sendMessage(m);
}
}
}
在本程式中Android仍然會自動替主線程建立Message Queue。在點選按鈕之後,新生成的子線程中并不會建立Message Queue。是以,新線程中的myLooper值為null,而mainLooper則指向主線程裡的Looper對象。于是,執行當到指令:
mHandler = new EHandler(mainLooper); 時這個mHandler是屬于主線程的。
通過指令:mHandler.sendMessage(m); 便将消息m存入到主線程的Message Queue裡。mainLooper看到Message Queue裡有訊息,就會自動處理,主線程會自動回調mHandler的handleMessage()函數來處理消息。
本文轉自 最牛傻蛋 51CTO部落格,原文連結:http://blog.51cto.com/zuiniuwang/718340,如需轉載請自行聯系原作者