博客转移到个人站点:
http://www.wangchengmeng.club/2018/02/04/Handler%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/
欢迎来吐槽
handler的原理
Handler
new Handler()
public Handler() { //1. this(null, false); } //2. public Handler(Callback callback, boolean async) { ... //获取轮询器 //3. 看4步 //9. mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } //10. 获取消息队列MessageQueue mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; } //4.Looper.myLooper(); return sThreadLocal.get(); //5. 赋值Looper(主线程) ActivityThread // 6. main() Looper.prepareMainLooper(); //7. Looper.prepareMainLooper(); prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } //8. prepare(false); private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } 总结:获取Looper器对象和消息队列
handler.sendMessage();
发送消息:看下面标记
Message
new Message
public Message() { }
Message.obtain()
public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) {// sPool Message Message m = sPool; sPool = m.next; m.next = null; sPoolSize--; return m; } } return new Message(); } 方法重载很多,每个方法的本质都会走上面代码
mHandler.obtainMessage()
Message.obtain(this); //把handler做绑定
Looper
- MessageQueue
ThreadLocal
- 线程的本地变量,每个线程都可以往tl里set值 ,取的时候根据线程的标记取出对应每个线程set的值
#发送消息
Message类中的 sendToTarget
public void sendToTarget() { target.sendMessage(this);(看2) }
mHandler.sendMessage(msg);
public final boolean sendMessage(Message msg) { //1. return sendMessageDelayed(msg, 0); } //2. sendMessageDelayed(msg, 0); public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } //3. return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } //4.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; } //5. 把handler绑定到message并且把消息放到消息队列并且按时间排序 return enqueueMessage(queue, msg, uptimeMillis); } //6.enqueueMessage(queue, msg, uptimeMillis) private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { //把Handler绑定到Message的target属性 msg.target = this;//this Handler对象 if (mAsynchronous) { msg.setAsynchronous(true); } //7. 把消息放到消息队列并且按时间排序 return queue.enqueueMessage(msg, uptimeMillis); } //8. MessageQueue的queue.enqueueMessage boolean enqueueMessage(Message msg, long when) { ... synchronized (this) { ... msg.when = when;//message的发送时间 Message p = mMessages;//mMessages MessagQueue的属性Message类型 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; } 。。。唤醒逻辑 } 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;
}
#取并处理消息
- Looper.loop();//轮询
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."); } //从轮询器中获取消息队列和Handler 的queue 是同一个消息队列 final MessageQueue queue = me.mQueue; ... for (;;) { //MessageQueue的next方法 //1. 取消息看2 Message msg = queue.next(); // might block //处理消息 //3. 处理消息看4 msg.target.dispatchMessage(msg); ... //回收消息 kan 6 msg.recycle(); } } // 2. MessageQueue的next方法 Message next() { int pendingIdleHandlerCount = -1; // -1 only during first iteration int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } // We can assume mPtr != 0 because the loop is obviously still running. // The looper will not call this method after the loop quits. nativePollOnce(mPtr, nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; if (msg != null) { if (now < msg.when) { // Next message is not ready. Set a timeout to wake up when it is ready. nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { // Got a message. mBlocked = false; if (prevMsg != null) { prevMsg.next = msg.next; } else { mMessages = msg.next; } msg.next = null; if (false) Log.v("MessageQueue", "Returning message: " + msg); msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1; } // Process the quit message now that all pending messages have been handled. if (mQuitting) { dispose(); return null; } // If first time idle, then get the number of idlers to run. // Idle handles only run if the queue is empty or if the first message // in the queue (possibly a barrier) is due to be handled in the future. if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; } if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); } // Run the idle handlers. // We only ever reach this code block during the first iteration. for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler boolean keep = false; try { keep = idler.queueIdle(); } catch (Throwable t) { Log.wtf("MessageQueue", "IdleHandler threw exception", t); } if (!keep) { synchronized (this) { mIdleHandlers.remove(idler); } } } // Reset the idle handler count to 0 so we do not run them again. pendingIdleHandlerCount = 0; // While calling an idle handler, a new message could have been delivered // so go back and look again for a pending message without waiting. nextPollTimeoutMillis = 0; } } //4. msg.target.dispatchMessage(msg); msg.target handler dispatchMessage 是handler的方法 public void dispatchMessage(Message msg) { if (msg.callback != null) { //回调 看5 handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } //处理消息 主线程调用 handleMessage(msg); } } //5. 回调 handleCallback(msg); private static void handleCallback(Message message) { message.callback.run();//主线程中调用 } //6. 回收消息(把消息放到消息池中) msg.recycle(); public void recycle() { //7. clearForRecycle(); synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } }
//7. clearForRecycle();
/package/ void clearForRecycle() {
flags = 0;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
when = 0;
target = null;
callback = null;
data = null;
}