前面分别介绍了Message、MessageQueue和Looper的功能及源码,介绍了Handler的特点、功能及用法,接下来分析Handler的源码。
Handler----负责handler 消息发送,提供发送和接收消息的接口。
Handler构造函数
// 是否需要查找潜在的漏洞 private static final boolean FIND_POTENTIAL_LEAKS = false; /** * 将Callback 接口作为构造方法参数,可以用作接收消息的回调 * 可省去自己重写 Handler 自身的 handleMessage 方法 * * @param msg 接收到的消息 * @return 是否需要进一步处理,即调用 Handler 自身的 handleMessage 方法*/ public interface Callback { public boolean handleMessage(Message msg); } final Looper mLooper; final MessageQueue mQueue; final Callback mCallback; final boolean mAsynchronous; // 发送的消息是否为异步的,默认是 false /** * @hide 隐藏的构造方法,外部不可见 */ 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()); } } // 得到当前线程的 Looper mLooper = Looper.myLooper(); // 如果 Looper 还没初始化抛出异常 if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } // 得到当前线程的 MessageQueue mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; } public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; } public Handler() { this(null, false); } public Handler(Callback callback) { this(callback, false); } public Handler(Looper looper) { this(looper, null, false); } public Handler(Looper looper, Callback callback) { this(looper, callback, false); } /** * @hide 隐藏的构造方法,外部不可见 */ public Handler(boolean async) { this(null, async); }
共7个构造函数,后面5个分别调用前两个。前两个的区别在于Looper的传递,没有Looper就调用Looper.myLooper()函数。对于handler发送消息sendMessage等方法最后调用的是将消息入队函数enqueueMessage()。
// 发送一条消息 public final boolean sendMessage(Message msg){ return sendMessageDelayed(msg, 0); } // 发送一条空消息 public final boolean sendEmptyMessage(int what){ return sendEmptyMessageDelayed(what, 0); } // 发送空的延时消息 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); } // 发送延时消息 public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } // 发送空的定时消息 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageAtTime(msg, uptimeMillis); } // 发送的定时消息 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); }
消息入队函数
Message的target 是 Handler 在发送消息前自己赋值的。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { // 将消息的宿主设置为当前 Handler 自身 msg.target = this; //如果 Handler 被设置成了异步就把消息也设置成异步的 if (mAsynchronous) { msg.setAsynchronous(true); } // 执行消息入队操作 return queue.enqueueMessage(msg, uptimeMillis); }
切换线程函数
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; } private static Message getPostMessage(Runnable r, Object token) { Message m = Message.obtain(); m.obj = token; m.callback = r; return m; } public final boolean post(Runnable r){ return sendMessageDelayed(getPostMessage(r), 0); } public final boolean postAtTime(Runnable r, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r), uptimeMillis); } public final boolean postAtTime(Runnable r, Object token, long uptimeMillis){ return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); } public final boolean postDelayed(Runnable r, long delayMillis){ return sendMessageDelayed(getPostMessage(r), delayMillis); } public final boolean postAtFrontOfQueue(Runnable r){ return sendMessageAtFrontOfQueue(getPostMessage(r)); }
postAtFrontOfQueue() 返回 sendMessageAtFrontOfQueue() 函数,实际操作为 when==0时将消息置于队列头部。
public final boolean sendMessageAtFrontOfQueue(Message msg) { 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, 0); }
消息接收函数
// Looper 分发消息 msg.target.dispatchMessage(msg);
消息入队enqueueMessage()函数可知,宿主 target 也就是我们的 Handler。若用 Post*() 方法发送的消息,Handler 接收到Message之后,最后运行 Message 对象的 Runnable 接口。 同时 mCallback 接口是完全可替代 Handler 来接收消息,因为其处理优先级高,甚至可以拦截接收的消息。
public void dispatchMessage(Message msg) { // 如果 Message 的 callback 不为空,表明通过 post*()方法发送的消息 if (msg.callback != null) { // 直接运行这个 callback handleCallback(msg); } else { //如果 mCallback 不为空,表明 Handler 设置了 Callback 接口先执行接口处理消息的方法 if (mCallback != null) { // 如果 callback 接口处理完消息返回 true 说明它将消息拦截 // 不再执行 Handler 自身的处理消息方法,直接结束方法 if (mCallback.handleMessage(msg)) { return; } } // 调用 Handler 自身处理消息的方法 handleMessage(msg); } } private static void handleCallback(Message message) { // 运行 callback,即 Runnable 接口 message.callback.run(); } // Handler 自身处理消息的方法,需要重写接收消息 public void handleMessage(Message msg) { }