很少废话, 上图:java
简单来讲handler流程就是handler 在消息池中获取msg 并发送给 MQ, 再由Looper进行轮询在MQ中获得待处理的msg交由handler进行 handleMessage(...);c++
这里主要涉及到了四个核心类: Message Handler MessageQueue Looper并发
那么下面来看看源码里面是怎么实现的:ide
1.
oop
Message类: 用来携带数据的载体ui
public int what; //标识this
public int arg1; //携带int类型数据spa
public int arg2; //携带int类型数据.net
public Object obj;//携带任意对象数据线程
long when; //保存要被处理的时间点
Handler target; //处理消息的handler
Runnable callback; //处理消息的回调器对象
Message next; //用来保存引用的下一个message(才能造成链表)
private static Message sPool; //存储处理过的消息的池 //在须要Message对象时复用
其中还有recycle()方法 Looper轮询过程当中中会用到
2.
Handler类: 进行消息的发送处理, 源码里面主要调用了以下几个方法:
sendMessage(Message msg)
public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0);//那咱们再去看看另外一个方法 }
sendEmptyMessage(int what)
public final boolean sendEmptyMessage(int what) { return sendEmptyMessageDelayed(what, 0);//和上面的同样 返回了一个延迟方法,那咱们去看看这个方法; }
sendMessageDelayed(Message msg, long delayMillis)
public final boolean sendMessageDelayed(Message msg, long delayMillis) { ... return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);//返回了atTime的方法,再继续:
sendMessageAtTime(Message msg, long uptimeMillis)
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { ... return enqueueMessage(queue, msg, uptimeMillis);//再去找这个方法 }
会发现全部的最后都是调用了这个方法:
sendMessageAtTime();//当前时间+延迟时间
而这个方法中调用了 enqueueMessage(),那么咱们来看看这里面到底实现了什么东西:
//源码
msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis);
里面是调用了MQ中的同名方法,下面就看看MessageQueue中主要的方法;
(handler中还有其余的关键方法 dispatchMessage(), Looper中会用到)
3. MessageQueue:
看一看源码中的enqueueMessage()方法;
boolean enqueueMessage(Message msg, long when) { ... msg.when = when; //将消息被处理的时间保存在msg上 //将msg对象保存到mMessages链表中一个合适的位置,msg会和mq中的msg的时间when进行比较, 当小于其中一个的时候会插入当前的位置; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { msg.next = p; mMessages = msg; needWake = mBlocked; } else { needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; 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; } //调用c或c++唤醒处理等待状态下的程序,防止阻塞 if (needWake) { nativeWake(mPtr); } } return true; }
能够发现里面主要作了三件事:
msg.when = when; //将消息被处理的时间保存在msg上
//将msg对象保存到mMessages链表中一个合适的位置
nativeWake(mPtr); //唤醒处理等待状态下的程序
//不是经过wait()来实现的, 而是经过C/C++的代码来实现的, 不会阻塞主线程
还有一个主要方法: next(), 很明显就是进行查询的,Looper中会用到
4. Looper:
其中主要有 loop()
static void loop() {
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; //拿到消息队列 // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // 获取到mq中的msg if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); //调用msg中的target(Handler对象)的dispatch...(msg)方法 if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycleUnchecked();//清除回收处理过的msg所携带数据和标识等,并将msg保存到消息池中 } }
能够看到loop()里面主要是调用了其余三个类中的方法:
a. mq.next();从mq中获取msg
b.handler.dispatchMessage(); handler进行分发消息 (源码里能够看出 此方法中有三个优先级的回调,而咱们经常使用的是 handleMessage(). 其实第一级是msg.callBack, 第二级是 handler中的CallBack{},最后才是handleMessage(),但通常状况下前二者为为空,因此一般咱们直接处理handleMessage()方法,代码以下
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
)
c.msg.recycleUnchecked(); 回收ms;
写的很差,主要目的是给本身复习一下,想系统地了解请点击以下连接: