Handler的底层实现
1.查看Handler源码的基本流程(其他类似)
首先查看Handler的构造方法,对初始化变量有一个大致的了解,然后开始走调用逻辑,Handler的sendMessage(),handleMessage()等等
2.Handler的大致原理
Handler:发送消息send,处理消息handle
Message:消息的实体,Handler通过sendMessage()将Message发送给消息队列MessageQueue
MessageQueue:消息队列,存储Message的消息队列
Looper:轮询(for(;;))消息队列中的消息,依次取出,然后交给handler处理
3.源码分析
Handler
public Handler(Callback callback) { this(callback, false); }
public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
看关键的地方,构造器主要初始化了Looper(mLooper)和MessageQueue(mQueue),并且mCallback存储了CallBack接口,也就是我们创建Handler传入的接口
Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { return false; } });
然后来看一下sendMessage()方法
public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0); }
可以看出最终调用了sendMessageDelayed()
public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
sendMessageDelayed只做了简单的判断,然后调用sendMessageAtTime(),需要说明一下SystemClock.uptimeMillis()指的是从开机到现在的毫秒数,不包括睡眠时间,下面看一下sendMessageAtTime()
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); }
往下看enqueueMessage()
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
需要注意msg.target,将msg和handler绑定在了一起,然后调用了MessageQueue中的enqueueMessage()方法,将消息放入MessageQueue消息队列中
MessageQueue
boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { throw new IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } synchronized (this) { if (mQuitting) { IllegalStateException e = new IllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); return false; } msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. 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; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
因为是直接在主线程中创建的Handler,所以Looper.loop()在ActivityThread中执行的
public static void main(String[] args) { Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); Looper.loop(); }
接着看Looper中的loop方法
Looper
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(); // might block 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); 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.target.dispatchMessage()方法,msg.target就是前面讲的Handler对象,调用了handler的dispatchMessage()方法,接着看这个方法
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
在讲dispatchMessage()方法之前,咱们先来看一下Handler的post方法,看一个最简单的
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }
调用了可以看出,同sendMessage一样,最后也是调用了sendMessageDelayed(),接着看一下getPostMessage()
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
可以看出,Message中的callback存储了r,下面接着分析dispatchMessage()方法的条件
第一个if条件
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
现在就知道了msg.callback实际上就是我们通过handler的post方法传入的runnable对象,所以第一个if其实就是最后回调了post中的runnable对象,并且runnble所在的线程和handler在同一个线程(注意)
private static void handleCallback(Message message) { message.callback.run(); }
else条件
mCallback对象,就是之前讲到的,构造器中储存的Handler的回调,
@Override public boolean handleMessage(Message msg) { return false; }
最后一个handleMessage(),通常是Handler的子类去重写handleMessage()