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() 函数,就将 消息发送 给主线程了。