不多废话, 上图:
简单来说handler流程就是handler 在消息池中获取msg 并发送给 MQ, 再由Looper进行轮询在MQ中得到待处理的msg交由handler进行 handleMessage(...);
这里主要涉及到了四个核心类: Message Handler MessageQueue Looper
那么下面来看看源码里面是怎么实现的:
1.
Message类: 用来携带数据的载体
public int what; //标识
public int arg1; //携带int类型数据
public int arg2; //携带int类型数据
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;
写的不好,主要目的是给自己复习一下,想系统地了解请点击如下链接:
http://blog.csdn.net/lmj623565791/article/details/38377229
来源:oschina
链接:https://my.oschina.net/u/2526599/blog/632856