[java] view plain copy print ? java
<EMBED id=ZeroClipboardMovie_1 height=14 name=ZeroClipboardMovie_1 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer width=29 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=1&width=29&height=14" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">android
网上以文档形式流传,不知道原文在哪,感谢原做者了! web
================简单调整了下格式就共享了===============================================安全
对于Android的Message机制主要涉及到三个主要的类,分别是Handler、Message、Looper;首先对每一个类作一个简单介绍;而后再介绍所谓的Android的Message机制是如何实现的,最后给了一个示例。app
1、介绍三个相关的类异步
一、 Handler主要有两个用途:首先是能够定时处理或者分发消息,其次是能够添加一个执行的行为在其它线程中执行,ide
对于Handler中的方法,能够选择你关心的操做去覆盖它,处理具体的业务操做,常见的就是对消息的处理能够覆盖public voidhandleMessage(参数)方法,能够根据参数选择对此消息是否须要作出处理,这个和具体的参数有关。例以下代码:函数
[java] view plain copy print ? oop
<EMBED id=ZeroClipboardMovie_2 height=14 name=ZeroClipboardMovie_2 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer width=29 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=2&width=29&height=14" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">post
Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {//覆盖handleMessage方法
switch (msg.what) {//根据收到的消息的what类型处理
case BUMP_MSG:
Log.v("handler", "Handler===="+msg.arg1);//打印收到的消息
break;
default:
super.handleMessage(msg);//这里最好对不须要或者不关心的消息抛给父类,避免丢失消息
break;
}
}
};
二、 消息android.os.Message
android.os.Message是定义一个Messge包含必要的描述和属性数据,而且此对象能够被发送给android.os.Handler处理。属性字段:arg一、arg二、what、obj、replyTo等;其中arg1和arg2是用来存放整型数据的;what是用来保存消息标示的;obj是Object类型的任意对象;replyTo是消息管理器,会关联到一个handler,handler就是处理其中的消息。一般对Message对象不是直接new出来的,只要调用handler中的obtainMessage方法来直接得到Message对象。
三、 Looper类主要用于一个线程循环获取消息队列中的消息。
Looper的做用主要是负责管理消息队列,负责消息的出列和入列操做。
2、Android的Message机制是如何实现?
一、为何要使用Message机制主要是为了保证线程之间操做安全,同时不须要关心具体的消息接收者,使消息自己和线程剥离开,这样就能够方便的实现定时、异步等操做。
二、Message机制原理示意图:
Activity <---------------> EHandler<-----> Looper<-----> MessageQueue
IntentReceiver <-----> EHandler <-----> Looper<-----> MessageQueue
图 1
三、 如何实现?(具体描述上图的消息流的过程)
实现Message机制须要Handler、Message、Looper三个之间的互相做用来实现;当线程A须要发消息给线程B的时候,线程B要用本身的Looper实例化Handler类,就是构造handler对象时,把当前线程的Looper传给Handler构造函数,handler自己会保存对Looper的引用,handler构造好之后,就能够用handler的obtainMessage方法实例化Message对象,只要把要传的数据给Handler,Handler就会构造Message对象,而且把Message对象添加到消息队列里面。而后就能够调用handler的sendMessage方法把Message对象发送出去,Looper就把消息放到消息队列中;最后当Looper知道消息队列不为空时候,就会循环的从消息队列中取消息,取出消息就会调用刚才实例化好的Handler对象的handleMessage方法取处理消息,整个Message过程就是这样。(如图1所示)
3、下面介绍一个关于Message机制的简单的示例,具体的代码以下:
一、 下面是一个新起的一个线程发消息的示例
handler自己不只能够发送消息,还能够用post的方式添加一个实现Runnable接口的匿名对象到消息队列中,在目标收到消息后就能够回调的方式在本身的线程中执行run的方法体,这就是handler两种典型的使用方式!
[java] view plain copy print ?
<EMBED id=ZeroClipboardMovie_3 height=14 name=ZeroClipboardMovie_3 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer width=29 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=3&width=29&height=14" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">
class NoLooperThread extends Thread {
private EventHandler mNoLooperThreadHandler;
public void run() {
Looper myLooper, mainLooper;
myLooper= Looper.myLooper(); //得到本身的Looper
mainLooper= Looper.getMainLooper(); //得到本身的main的looper
String obj;
if (myLooper == null) {
mNoLooperThreadHandler = new EventHandler(mainLooper);
obj= "NoLooperThread has no looper andhandleMessage function executed in main thread!";
}else
{
mNoLooperThreadHandler = new EventHandler(myLooper);
obj= "This is from NoLooperThread self andhandleMessage function executed in NoLooperThread!";
}
mNoLooperThreadHandler.removeMessages(0); //清空消息队列
if (false == postRunnable) {
Message m = mNoLooperThreadHandler.obtainMessage(2, 1, 1, obj); //生成消息对象
mNoLooperThreadHandler.sendMessage(m); //发送消息
Log.e(sTag, "NoLooperThread id:" + this.getId());
}else {
mNoLooperThreadHandler.post(new Runnable() { //添加一个Runnable接口的实现到消息队列,此Runnable接口的实现不在此 线程中执行,会在接收的线程中执行。
public void run() {
tv.setText("update UI through handler post runnalbe mechanism!");
noLooerThread.stop();
}
});
}
}
二、下面是一个定时循环发消息的示例,以下代码:
详细的解释参考代码的注释
Handler handler = new Handler() { //建立处理对象handler
publicvoid handleMessage(Message msg) {
switch (msg.what) {
caseMES: {
final int N = mCallbacks.beginBroadcast(); //Copy一份回调list,而且标记一个状态
for (int i = 0; i <N; i++) {
try {
mCallbacks.getBroadcastItem(i).getValue(mMediaPlayer01.getCurrentPosition()); //遍历全部回调接口 }catch (Exception e) {
e.printStackTrace();
}
}
mCallbacks.finishBroadcast(); //完成后状态复位
sendMessageDelayed(obtainMessage(MES),1 * 1000);
}
break;
default:
super.handleMessage(msg);
}
}
};
NOTE: 整个hadleMessage方法至关一个嵌套的循环
4、总结:
所谓的消息机制其实很简单,实现这种机制须要只须要四步:
一、实例化Looper(由于实例化Handler时须要一个looper);
二、实例化Handler,这里须要覆盖handleMessage方法,处理收到的消息;
三、 实例化Message对象,调用已经实例化好的handler对象的obtainMessage方法,把数据传给obtainMessage方法,obtainMessage方法就会实例化一个Message对象。(这里也能够发送实现Runnable接口的对象);
四、调用Handler的sendMessage方法把实例化好的Message对象发送出去。
对每一个线程过程都是同样的,只要按照上面的四个步骤来就能够发送和接收消息了。