引言:
最近公司项目做了一些比较大的重构,很多地方都用了Handler.post(Runnable r),这个方法,比如这一段
Handler mHandler = new Handler(); mHandler.post(new Runnable() { @Override public void run() { showContentView(contentView); } });
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }它把Runnable重新封装了一遍然后调用了sendMessageDelayed方法
private final Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }看到了吧,用过Handler的都知道Message是用来记录信息的最小单元,这里把Runnable封装到一个Message对象并返回
public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }这里就是对delayMillis做了一下有效性检测
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { boolean sent = false; MessageQueue queue = mQueue; if (queue != null) { msg.target = this; sent = queue.enqueueMessage(msg, uptimeMillis); } else { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); } return sent; }Handler对象把Message压到了MessageQueue队列里面
public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block //if (!me.mRun) { // break; //} if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } if (me.mLogging!= null) me.mLogging.println( ">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what ); msg.target.dispatchMessage(msg); if (me.mLogging!= null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback); msg.recycle(); } } }Looper对象把MessageQueue里面的Message逐个取出来,注意看msg.target.dispatchMessage(msg)这一句。
然后就是调用我们的handler里面的dispatchMessage(msg)方法了
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }看到没有,一开始我们的Runnable传进来,然后调用GetPostMessage方法把Runnable赋值给了Massage里面的callback,
private final void handleCallback(Message message) { message.callback.run(); }