1.复习Message Queue的角色

在上一篇里,介绍了AndroidThreadLooperMessage QueueHandler四者间之关系。

先复习如下:

lUI thread通常就是main thread,而Android启动程序时(即创建Process)会替它建立一个Message Queue

l当然需要一个Looper对象,来管理该Message Queue

l我们可以创建Handler对象来push新消息到Message Queue里;或者接收Looper(Message Queue取出)所送来的消息。

l线程AHandler对象引用可以传递给别的线程,让别的线程BC等能发送消息来给线程A(存于AMessage Queue)

l线程AMessage Queue里的消息,只有线程A所属的对象可以处理之

了解了四者间之关系后,在本篇里,就能来思考如何让主线程与子线程之间互相沟通了。包括,子线程push消息到主线程的Message Queue里,并触发主线程去执行某项工作(即执行某个函数)

2.由别的线程发送消息到主线程的Message Queue()

在上一篇文章里,使用如下程序片段:

//classac01extendsActivity {

// ………

publicvoidonClick(View v) {

switch(v.getId()){

case101:

t=newmyThread();

t.start();

break;

case102:

finish();

break;

}

}

//------------------------------------------------------

classEHandlerextendsHandler {

publicEHandler(Looper looper) {

super(looper);

}

@Override

publicvoidhandleMessage(Message msg) {

tv.setText((String)msg.obj);

}

}

//------------------------------------------------------

classmyThreadextendsThread{

privateEHandlermHandler;

publicvoidrun() {

Looper myLooper, mainLooper;

myLooper = Looper.myLooper();

mainLooper = Looper.getMainLooper();

String obj;

if(myLooper ==null){

mHandler=newEHandler(mainLooper);

obj ="current thread has no looper!";

}

else{

mHandler=newEHandler(myLooper);

obj ="This is from current thread.";

}

mHandler.removeMessages(0);

Message m =mHandler.obtainMessage(1, 1, 1, obj);

mHandler.sendMessage(m);

}

}

}

这个mHandler定义于myThread类别里,而且由子线程执行指令:mHandler=newEHandler(mainLooper);

来创建EHandler对象;但是这个mHandler确是属于main线程的(用来存取主线程的MessageQueue),所以指令:

mHandler.sendMessage(m);是将m丢到主线程的MessageQueue里。

此外,我们也可以将mHandler定义于ac01类别里。如下程序范例:

//----- Looper_03范例-----

publicclassac01extendsActivityimplementsOnClickListener {

privatefinalintWC= LinearLayout.LayoutParams.WRAP_CONTENT;

privatefinalintFP= LinearLayout.LayoutParams.FILL_PARENT;

publicTextViewtv;

privatemyThreadt;

privateButtonbtn,btn2;

EventHandlerh;

Contextctx;

publicvoidonCreate(Bundle icicle) {

super.onCreate(icicle);

ctx=this;

LinearLayout layout =newLinearLayout(this);

layout.setOrientation(LinearLayout.VERTICAL);

btn=newButton(this);

btn.setId(101);

btn.setBackgroundResource(R.drawable.heart);

btn.setText("test looper");

btn.setOnClickListener(this);

LinearLayout.LayoutParams param =

newLinearLayout.LayoutParams(100,50);

param.topMargin= 10;

layout.addView(btn, param);

btn2=newButton(this);

btn2.setId(102);

btn2.setBackgroundResource(R.drawable.ok_blue);

btn2.setText("exit");

btn2.setOnClickListener(this);

layout.addView(btn2, param);

tv=newTextView(this);

tv.setTextColor(Color.WHITE);

tv.setText("");

LinearLayout.LayoutParams param2 =

newLinearLayout.LayoutParams(FP,WC);

param2.topMargin= 10;

layout.addView(tv, param2);

setContentView(layout);

}

publicvoidonClick(View v) {

switch(v.getId()){

case101:

h=newEventHandler(Looper.myLooper());

t=newmyThread();

t.start();

break;

case102:

finish();

break;

}

}

//------------------------------------------------

publicclassEventHandlerextendsHandler {

publicEventHandler(Looper looper) {

super(looper);

}

@Override

publicvoidhandleMessage(Message msg) {

((Activity)ctx).setTitle((String)msg.obj);

}

}

//------------------------------------------------------

classmyThreadextendsThread{

publicvoidrun() {

String obj ="from myThread";

Message m =h.obtainMessage(1, 1, 1, obj);

h.sendMessage(m);

}

}

}

//------------------------------------------------------

指令:h=newEventHandler(Looper.myLooper());

h是属于main线程的(用来存取主线程的MessageQueue)。在myThread类别里的指令:h.sendMessage(m);

虽然是由子线程执行该指令,还是将m丢到主线程的MessageQueue里。于是,子线程所执行的run()函数,就顺利将m丢给主线程(Message Queue),并触发了主线程去执行handleMessage()函数了。显示出画面如下:

1

上述的指令:

myLooper = Looper.myLooper();

mainLooper = Looper.getMainLooper();

………

mHandler=newEHandler(mainLooper);

………

mHandler=newEHandler(myLooper);

………

明显地指明mHandler是负责存取哪一个线程的Message Queue。不过,有时候并不需要特别指明。例如上述的onClick()函数和EventHandler类别,可改写为:

//----- Looper_03aa范例-----

//classac01extendsActivity {

// ………

publicvoidonClick(View v) {

switch(v.getId()){

case101:

h=newEventHandler();

t=newmyThread();

t.start();

break;

case102:

finish();

break;

}

}

//------------------------------------------------

publicclassEventHandlerextendsHandler {

@Override

publicvoidhandleMessage(Message msg) {

((Activity)ctx).setTitle((String)msg.obj);

}

}

//------------------------------------------------------

classmyThreadextendsThread{

publicvoidrun() {

String obj ="from myThread";

Message m =h.obtainMessage(1, 1, 1, obj);

h.sendMessage(m);

}

}

}

指令:h=newEventHandler(); 就等于:h = new EventHandler(Looper.myLooper());

它建立了当前线程(Current Thread)EventHandler对象。于此,是由main线程执行此指令的,所以此EventHandler对象是用来存取main线程的Message Queue

上述程序将handleMessage()定义于EventHandler类别内,也可以直接定义于ac01类别之内。于是上述程序,也相当于:

//----- Looper_03bb范例-----

//classac01extendsActivity {

// ………

publicvoidonClick(View v) {

switch(v.getId()){

case101:

h=newHandler(){

publicvoidhandleMessage(Message msg) {

((Activity)ctx).setTitle((String)msg.obj);

}};

t=newmyThread();

t.start();

break;

case102:

finish();

break;

}

}

//------------------------------------------------------

classmyThreadextendsThread{

publicvoidrun() {

String obj ="from myThread...";

Message m =h.obtainMessage(1, 1, 1, obj);

h.sendMessage(m);

}

}

}

其执行结果是一样的。

转自:http://www.android1.net/Topic.aspx?BoardID=11&TopicID=631

更多相关文章

  1. Android的线程使用来更新UI----Thread、Handler、Looper、TimerT
  2. Android异步消息处理机制(源码分析+面试题)
  3. SurfaceView 的基本使用
  4. Android(安卓)之AsyncHttpClient
  5. android 线程中的ui问题 Handler的基本使用 关于获取动态时间在u
  6. E/错误(3907): android.view.ViewRootImpl$CalledFromWrongThrea
  7. Android(安卓)DVM
  8. 有关Android线程的学习
  9. Android深入浅出之Binder机制

随机推荐

  1. Android在layout xml中使用include
  2. android保持在休眠时,后台程序继续运行(让
  3. Android的SMS短消息格式和主要字段
  4. 动画学习笔记-Android(安卓)Animation
  5. Android权限问题整理
  6. android如何调用显示和隐藏系统默认的输
  7. Android(安卓)手动显示和隐藏软键盘 andr
  8. Android编程示例之——横竖屏切换动画
  9. Gradle for Android(安卓)脚本编写总结
  10. Ubuntu搭建Eclipse+JDK+SDK的Android