活用Android的Message Queue(3)
3.??由主线程发送消息给子线程(续)
????上述范例里,是由子线程发送消息给主线程。本节将介绍如何从主线程发送消息给子线程。其方法是:当子线程执行run()函数时,就创建一个子线程的Handler对象。之后,当主线程执行ac01的onClick()函数时,就藉由此Handler对象引用而push消息给子线程。例如下述范例:
?
//----- Looper_04范例?-----
public?class?ac01?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;
????private?Handler?h;
????private?Context?ctx;
????public?void?onCreate(Bundle icicle) {
????????????super.onCreate(icicle);
????????????ctx?=?this;
????????????????LinearLayout layout =?new?LinearLayout(this);
????????????????layout.setOrientation(LinearLayout.VERTICAL);
??????????????????????????????
????????????????btn?=?new?Button(this);
????????????????btn.setId(101);
????????????????btn.setBackgroundResource(R.drawable.heart);
????????????????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.setBackgroundResource(R.drawable.ok_blue);
????????????????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);?
????????????????//------------------------
????????????????t?=?new?myThread();
?????????????????t.start();
??????????}
??????????public?void?onClick(View v) {
????????switch(v.getId()){
????????case?101:
?????????????String obj =?"mainThread";
?????????????Message m =?h.obtainMessage(1, 1, 1, obj);
?????????????h.sendMessage(m);
?????????????break;
????????case?102:
????????????h.getLooper().quit();
????????finish();
????????????break;
????????}
????}
//------------------------------------------------?????
public?class?EventHandler?extends?Handler {
??????????public?EventHandler(Looper looper) {
??????????????????????super(looper);
??????????}
???????????@Override
??????????????public?void?handleMessage(Message msg) {
?????????????????????((Activity)ctx).setTitle((String)msg.obj);
????????????}
????????}
//------------------------------------------------?????
class?myThread?extends?Thread{
?????public?void?run() {
?????????Looper.prepare();
?????????h?=?new?Handler(){
???????????????public?void?handleMessage(Message msg) {
??????????????????EventHandler ha =?new
?????????????????????EventHandler(Looper.getMainLooper());
????????????????????String obj = (String)msg.obj?+?", myThread";
?????????????????????Message m = ha.obtainMessage(1, 1, 1, obj);
?????????????????????ha.sendMessage(m);
?????????}
?????????};
?????????Looper.loop();
??????}
??}
}
?
?
当子线程执行run()函数时,创建一个主线程的EventHandler对象,并且藉之而push消息给主线程了。就进行了两个线程之间的互相交换消息,也是两个函数或对象间之交换消息。此程序输出画面为:
?
? 
图2
?
?????上述范例定义了Thread的子类别。也可以将子线程包含到Runnable类别里,如下:
?
//----- Looper_04aa范例?-----
public?class?ac01?extends?Activity?implements?OnClickListener {
????private?final?int?WC?= LinearLayout.LayoutParams.WRAP_CONTENT;
????private?final?int?FP?= LinearLayout.LayoutParams.FILL_PARENT;
????public?TextView?tv;
????private?RR?r;
????private?Button?btn,?btn2;
????private?Handler?h;
????private?Context?ctx;
????public?void?onCreate(Bundle icicle) {
????????????super.onCreate(icicle);
????????????ctx?=?this;
????????????????LinearLayout layout =?new?LinearLayout(this);
????????????????layout.setOrientation(LinearLayout.VERTICAL);
??????????????????????????????
????????????????btn?=?new?Button(this);
????????????????btn.setId(101);
????????????????btn.setBackgroundResource(R.drawable.heart);
????????????????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.setBackgroundResource(R.drawable.ok_blue);
????????????????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);?
????????????????//------------------------
????????????????r?=?new?RR();
?????????}
??????????public?void?onClick(View v) {
????????switch(v.getId()){
????????case?101:
?????????????String obj =?"mainThread";
?????????????Message m =?h.obtainMessage(1, 1, 1, obj);
?????????????h.sendMessage(m);
?????????????break;
????????case?102:
????????????h.getLooper().quit();
????????finish();
????????????break;
????????}
????}
//------------------------------------------------??????
public?class?EventHandler?extends?Handler {
??????????public?EventHandler(Looper looper) {
??????????????????????super(looper);
??????????}
???????????@Override
??????????????public?void?handleMessage(Message msg) {
?????????????????????((Activity)ctx).setTitle((String)msg.obj);
????????????}
????????}
//------------------------------------------------?????
public?class?RR?implements?Runnable {
????public?RR() {
????????Thread aThread =?new?Thread(null,?this,?"RR");
????????aThread.start();
????}
????public?void?run() {
?????????Looper.prepare();
?????????h?=?new?Handler(){
???????????????public?void?handleMessage(Message msg) {
??????????????????EventHandler ha =?new?EventHandler(Looper.getMainLooper());
????????????????????String obj = (String)msg.obj?+?", myThread";
?????????????????????Message m = ha.obtainMessage(1, 1, 1, obj);
?????????????????????ha.sendMessage(m);
?????????}
?????????};
?????????Looper.loop();
??????}
??}
}
?
?
当子线程执行到RR()函数时,创建一个子线程,并执行run()函数,就将消息发送给主线程了。