转载部分来自: http://gundumw100.iteye.com/blog/858233
转载部分对于应用层非常简洁明了
原创部分是基于Android4.4源代码,有什么错误或不足,欢迎指正
转载部分:
一、几个关键概念
1、MessageQueue:是一种 数据 结构,见名知义,就是一个消息队列,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构。
创建一个线程的时候,并不会自动 创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。其他非主线程,不会自动创建Looper,要需要的时候,通过调用prepare函数来实现。
2、Message:消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message。
Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。如果Message Pool中没有可用的Message实例,则才用给定的参数创建一个Message对象。调用removeMessages()时,将Message从Message
Queue中删除,同时放入到Message Pool中。除了上面这种方式,也可以通过Handler对象的obtainMessage()获取 一个Message实例。
3、Looper:
是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象
创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能接受Message。如需要接受,自己定义 一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。
Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入Message Pool中。
4、Handler:
消息的处理者,handler 负责将需要传递的信息封装成Message,通过调用handler 对象的obtainMessage()来实现;
将消息传递给Looper,这是通过handler 对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。
当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler 对象收到该消息后,调用相应的handler 对象的handleMessage()方法对其进行处理。
二、线程之间的消息如何进行传递
1、主线程给自己发送Message
原创部分:
以PowerMangerService里的handler为例,说明一下handler具体实现过程
总的来说就是handler往MessageQueue里放消息,Looper.loop()从消息队列中读消息,调用handler对象的Handlemessage处理队列里的消息。
PowerManagerService.java:
public void init(Context context,LightsService ls,
ActivityManagerService am, BatteryService bs, IBatteryStats bss,
IAppOpsService appOps, DisplayManagerService dm) {
……
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = newPowerManagerHandler(mHandlerThread.getLooper());
}
HandlerThread.java:
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
mHandlerThread.start();会调用此run函数
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare(); \\会new looper
synchronized (this) {
mLooper =Looper.myLooper(); \\获取上步new的looper
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop(); \\循环监视messageQueue
mTid = -1;
}
下面逐个分析run函数里的这几个方法:
public static void prepare() {
prepare(true);
}
private static void prepare(booleanquitAllowed) {
if (sThreadLocal.get() != null) {
throw newRuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed)); \\newlooper
}
private Looper(boolean quitAllowed) {
//new looper时候new出handler对应的MessageQueue
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread(); //looper跟线程关联
}
-----------------------------------------------------
Looper.loop();
/**
* Run the message queue in this thread. Besure to call
* {@link #quit()} to end the loop.
*/
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("NoLooper; Looper.prepare() wasn‘t called on this thread.");
}
final MessageQueue queue = me.mQueue;
// Make sure the identity of thisthread is that of the local process,
// and keep track of what that identitytoken actually is.
Binder.clearCallingIdentity();
final long ident =Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // mightblock//循环查看消息队列
if (msg == null) {
// No message indicates thatthe message queue is quitting.
return;
}
………
//messagequeue里有消息就会调到此方法 target为发送msg时候赋值的对应handler
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " +msg.target + " " + msg.callback);
}
// Make sure that during the courseof dispatching the
// identity of the thread wasn‘tcorrupted.
final long newIdent =Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Threadidentity changed from 0x"
+Long.toHexString(ident) + " to 0x"
+Long.toHexString(newIdent) + " while dispatching to "
+msg.target.getClass().getName() + " "
+ msg.callback + "what=" + msg.what);
}
msg.recycle(); //把这个msg实例放回到goable pool
}
}
Handler.java
/**
* Handle system messages here.
*/
public voiddispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)){
return;
}
}
handleMessage(msg); \\这就是newhandler时候@override的handlemessage(msg)
}
}
/**
* Return a Message instance to the globalpool. You MUST NOT touch
* the Message after calling this function-- it has effectively been
* freed.
*/
public void recycle() {
clearForRecycle(); //msg里信息清楚
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this; 添加到sPool里 message msg = handler.obtain()就是从sPool里分配一个message对象
sPoolSize++;
}
}
}
创建和接收到此为止,下面说下handler怎么把msg发送到到MessageQueue里的
Handler.sendEmptyMessageAtTime(int what, longuptimeMillis)为例:
public final booleansendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
returnsendMessageAtTime(msg, uptimeMillis);
}
public boolean sendMessageAtTime(Messagemsg, long uptimeMillis) {
//把handler对象的MessageQueue赋给queue
MessageQueuequeue = mQueue;
if (queue == null) {
RuntimeException e = newRuntimeException(
this + "sendMessageAtTime() called with no mQueue");
Log.w("Looper",e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg,uptimeMillis);
}
private boolean enqueueMessage(MessageQueuequeue, Message msg, long uptimeMillis) {
msg.target =this; //上面再loop里用到的target赋值 this为当前handler对象
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg,uptimeMillis); //MessageQueue.java里
}
MessageQueue.java:
booleanenqueueMessage(Message msg, long when) {
if (msg.isInUse()) {
throw newAndroidRuntimeException(msg + " This message is already in use.");
}
if (msg.target== null) { //判断设置的target是否为NULL
throw newAndroidRuntimeException("Message must have a target.");
}
synchronized (this) {
if (mQuitting) {
RuntimeException e = newRuntimeException(
msg.target + " sending message toa Handler on a dead thread");
Log.w("MessageQueue",e.getMessage(), e);
return false;
}
msg.when = when;
Message p = mMessages; //mMessages为队列里最新的一个Message
boolean needWake;
if (p == null || when == 0 || when< p.when) {
// New head, wake up the eventqueue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middleof the queue. Usually we don‘t have towake
// up the event queue unlessthere is a barrier at the head of the queue
// and the message is theearliest asynchronous message in the queue.
needWake = mBlocked &&p.target == null && msg.isAsynchronous();
Message prev;
//把msg加到MessageQueue里此函数执行完后再loop循环里就可以读取到此消息
for (;;) {
prev = p;
p = p.next;
if(p == null || when < p.when) {
break;
}
if(needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 becausemQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
一个handler 只能对应一个Looper 一个MessageQueue
一个Thread 只能有一个Looper
New Handler()时候如果没有传入Looper默认用主线程的Looper作为此handler的Looper
Handler,Looper,MessageQueue,Message总结
原文地址:http://blog.csdn.net/m346759541/article/details/45723367