1.Message Queue的角色

l在你的Android程序里,新创建一个线程,或称线程(Thread)时,并不会自动建立其Message Loop

lAndroid里并没有GlobalMessage Queue数据结构,例如,不同APK里的对象不能透过Massage Queue来交换消息(Message)

l一个线程可以创建一个Looper对象,由它来管理此线程里的Message Queue

l你可以创建Handler对象来与Looper沟通,以便push新消息到Message Queue里或者接收Looper(Message Queue取出)所送来的消息。

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

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

l使用Looper.myLooper可以取得目前线程的Looper对象引用。

l使用mHandler =newEventHandler(Looper.myLooper());可创建用来处理目前线程的Handler对象;其中,EventHandlerHandler的子类别。

l使用mHandler =newEventHandler(Looper.getMainLooper());可创建用来处理main线程的Handler对象;其中,EventHandlerHandler的子类别。

2.范例之一:Looper类之角色

Looper类别用来管理特定线程内对象之间的消息交换(Message Exchange)。你的应用程序可以创建许多个线程,或称线程(Thread)。而一个线程可以实例化许多个对象,这些对象之间常常需要互相交换消息。如果有这种需要,您可以替线程创建一个Looper类对象,来处理信息交换的管理工作。Looper对象会建立一个MessageQueue数据结构来存放各对象传来的消息(包括UI事件或System事件等)。如下图:

每一个线程(Thread,或称「线程」)里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息

//----- Looper_01范例-----

packagecom.misoo.kx04;

importandroid.app.Activity;

importandroid.graphics.Color;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Looper;

importandroid.os.Message;

importandroid.view.View;

importandroid.view.View.OnClickListener;

importandroid.widget.Button;

importandroid.widget.LinearLayout;

importandroid.widget.TextView;

publicclassac01extendsActivityimplementsOnClickListener {

privatefinalintWC= LinearLayout.LayoutParams.WRAP_CONTENT;

privatefinalintFP= LinearLayout.LayoutParams.FILL_PARENT;

publicTextViewtv;

privateEventHandlermHandler;

privateButtonbtn,btn2,btn3;

publicvoidonCreate(Bundle icicle) {

super.onCreate(icicle);

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: Looper looper;

looper = Looper.myLooper();

mHandler=newEventHandler(looper);

mHandler.removeMessages(0);

//清除整个MessageQueue里的事件,确保不会通知到别人

String obj ="This my message!";

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

//组装成一个Message物件

mHandler.sendMessage(m);

//Message物件送入MessageQueue

break;

case102:

finish();

break;

}

}

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

classEventHandlerextendsHandler{

publicEventHandler(Looper looper) {

super(looper);

}

@Override

publicvoidhandleMessage(Message msg) {

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

}

}

}

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

说明:

程序启动时,当前线程(即主线程, main thread)已创建了一个Looper对象,并且有了一个MessageQueue数据结构。

指令:looper = Looper.myLooper();调用Looper类的静态myLooper()函数,以取得目前线程里的Looper对象引用。

指令:mHandler=newEventHandler(looper);创建一个EventHandler对象来与Looper沟通。Activity等对象可以通过EventHandler对象来将消息传给Looper,然后放入MessageQueue里;EventHandler对象也扮演Listener的角色,可接收Looper对象所送来的消息。如下图:

指令:Message m =mHandler.obtainMessage(1, 1, 1, obj); 先创建一个Message对象,并将数据存入次对象里。

指令:mHandler.sendMessage(m); 通过mHandler对象而将消息m传给Looper,然后放入MessageQueue里。

此时Looper对象看到MessageQueue里有消息m就将它广播出去 mHandler对象接到此消息时,会调用其handleMessage()函数来处理之,于是输出"This my message!"于画面上,如下:

3.范例之二:由别的线程发送到主线程的Message Queue

//----- Looper_02范例-----

packagecom.misoo.kx04;

importandroid.app.Activity;

importandroid.graphics.Color;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Looper;

importandroid.os.Message;

importandroid.view.View;

importandroid.view.View.OnClickListener;

importandroid.widget.Button;

importandroid.widget.LinearLayout;

importandroid.widget.TextView;

publicclassac01extendsActivityimplementsOnClickListener {

privatefinalintWC= LinearLayout.LayoutParams.WRAP_CONTENT;

privatefinalintFP= LinearLayout.LayoutParams.FILL_PARENT;

publicTextViewtv;

privatemyThreadt;

privateButtonbtn,btn2,btn3;

publicvoidonCreate(Bundle icicle) {

//文章长度有限,代码请参考上例

}

publicvoidonClick(View v) {

switch(v.getId()){

case101:

t=newmyThread();

t.start();

break;

case102:

finish();

break;

}

}

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

classEHandlerextendsHandler {//文章长度有限,代码请参考上例

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

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);

}

}

}

Android会自动替主线程建立Message Queue 在这个子线程里并没有建立Message Queue。所以,myLooper值为null,而mainLooper则指向主线程里的Looper对象。于是,执行到指令:

mHandler =newEHandler(mainLooper);mHandler属于主线程

指令:mHandler.sendMessage(m);

就将消息m存入到主线程的Message Queue里。mainLooper看到Message Queue里有消息,就会处理之,于是由主线程执行到mHandlerhandleMessage()函数来处理消息。此程序输出画面为:

更多相关文章

  1. Android(安卓)组件系列-----Activity的传值和回传值
  2. Android多线程之HandlerThread
  3. Android内存泄漏检测工具使用手册
  4. 编写高效的Android代码(译)
  5. android异步处理Handler+Thread使用进阶
  6. Android(安卓)- Parcelable接口用法 和 与 Serializable 的区别
  7. Android(安卓)消息机制问题总结
  8. 【Android】在不同的线程池中执行AsyncTask
  9. Android温故之-BroadcastReceiver

随机推荐

  1. coremail导出用户草稿箱中的邮件并打包
  2. HBase社区福利 | HBase初学者
  3. EGG Network公链生态应用 EFTalk阿凡提
  4. HBase应用 | 云HBase Spark分析引擎对接
  5. 技术分享:Python如何进行内存管理?
  6. 什么是整型类型?Python整型详细介绍
  7. HBase分享 | HBase生态实践
  8. 对象池 GenericObjectPool 配置参数详解
  9. Phoenix实战 | Phoenix ODPSBulkLoadTool
  10. dns查询3:Test