什么是Handler?windows
Android 的官方解释:app
文档分节1:A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
这个解释给咱们释放出如下几个信息:less
一 Handler能够发送和处理两种类型的事物:async
1,Message;ide
2,实现Runnable接口的对象oop
二,每一个Handler实例都会跟建立Handler的Thread及这个Thread下的MessageQueue相关联。post
文档分节2:There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
Handler主要有两个做用:ui
1,能够设定某个时间点去执行Message和Runnable对象this
2,能够在不一样的线程中去执行某项任务spa
文档分节3:Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long),sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler).
Handler主要提供了两种方式来调度消息:
1,post方式:处理Runnable对象
2,sendmessage方式:在Message中放入Bundle data,这个消息会在Handler提供的handleMessage(Message)方法中去处理;
文档分节4:When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-basedbehavior.
When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. Thegiven Runnable or Message will then be scheduled in the Handler's message queue and processed when appropriate.
1,咱们可让handler立刻或者指定一个时间间隔发送消息;
2,当咱们的应用开启时,UI线程会自动帮咱们建立好MessageQueue,咱们也能够在本身定义的Thread中建立。
这些信息咱们如今只要稍微有个概念就好,一会进入Handler的深刻分析以后,天然就会清楚,咱们先来分析一下Handler的源码:
先来看看Handler主要的成员变量:
final MessageQueue mQueue; final Looper mLooper; final Callback mCallback; final boolean mAsynchronous; IMessenger mMessenger;
咱们先粗略地看一下,Handler这个类里面有MessageQueue,从名称中咱们能够猜想,这个就应该是消息队列了,第二个成员变量:Looper,从名称来看,应该是个推进消息循环的角色,第三个成员变量:Callback,应该是个回调的接口,剩下的两个先暂时忽略,这三个比较重要的成员变量我们先混个眼熟,打个招呼就好,如今咱们来看一下这个类的构造方法,依次先从最简洁的构造方法看起:
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); }
public Handler(boolean async) { this(null, async); }
1 public Handler(Callback callback, boolean async) { 2 if (FIND_POTENTIAL_LEAKS) { 3 final Class<? extends Handler> klass = getClass(); 4 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 5 (klass.getModifiers() & Modifier.STATIC) == 0) {
//想必你们对下面这句话不陌生吧?细心的朋友们会常常在开发环境中看到这句黄色警告(该Handler可能会致使内存泄漏),后面的系列咱们再给出解决这个警告的示例代码 6 Log.w(TAG, "The following Handler class should be static or leaks might occur: " + 7 klass.getCanonicalName()); 8 }
9 } 10 11 mLooper = Looper.myLooper(); 12 if (mLooper == null) { 13 throw new RuntimeException(
//这个抛出的异常信息你们也可能一不当心就会看到 14 "Can't create handler inside thread that has not called Looper.prepare()"); 15 } 16 mQueue = mLooper.mQueue; 17 mCallback = callback; 18 mAsynchronous = async; 19 }
1 public Handler(Looper looper, Callback callback, boolean async) { 2 mLooper = looper; 3 mQueue = looper.mQueue; 4 mCallback = callback; 5 mAsynchronous = async; 6 }
我了个大去,稍微看去洋洋洒洒出现了7个构造方法,仔细看下,其实前面五种构造方法都调用到了最后两种构造方法中的一种,那么咱们就着重来看一下这两个构造方法
public Handler(Callback callback, boolean async)的构造方法里面都干了些啥?
1,经过Looper的myLooper()方法,获得一个Looper对象,将之传给Handler的成员变量mLooper;
若是拿到的这个对象为null,就会抛出异常,从异常的信息来看,说是没有在建立Handler的时候去调用Looper的prepare()方法;
2,从获得的Looper对象拿出MessageQueue对象,传给Handler的成员变量mQueue;
3,将入参callback传给Handler的成员变量mCallback;
看到这里,朋友们可能会发现这个Looper看来是个重要角色啊,忍不住想去一窥究竟,先忍一忍,好戏老是在后头,先来看一下另一个重要的构造方法
public Handler(Looper looper, Callback callback, boolean async)
其实这个方法作的就是上面那个构造方法的事情,只不过,mLooper,mQueue,mCallback都是在调用以前就已经建立好了,直接赋值而已
上面已经看了Handler这个类的成员变量,构造方法,那么,咱们如今就来看一下这个类里面都给外部提供了哪些接口和方法
public interface Callback { public boolean handleMessage(Message msg); }
原来Callback真的就是一个接口,提供了一个回调的方法 handleMessage(Message msg),这个方法的名字有点熟悉,是否是就是咱们常常见到的那个在新建立一个Handler的时候,须要覆盖的方法呢?先带着疑问往下看,
/** * Subclasses must implement this to receive messages. */ public void handleMessage(Message msg) { }
看到这个类的注解,你们立刻发现上面的疑问是本身多想了,两个方法虽然同名,可是返回类型不一样啊,原来这个方法才是咱们常见的那个须要覆盖的方法。
接着往下看,
在文章开头的文档分节3中,咱们知道,Handler主要提供了两种方式来发送消息,一种是postXX方法,一种是sendMessageXX方法
果真,咱们看到了大量的post和sendmessage方法
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 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 sendEmptyMessageAtTime(int what, long uptimeMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageAtTime(msg, uptimeMillis); }
public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
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); }
细心的朋友们仔细一看,就能发现,其实不论是postXX仍是sendMessageXX方法,最终调用的都是sendMessageAtTime这个方法,postXX方法只是否是多调了getPostMessage()方法而已 ,那么咱们就来看一下这个方法作了些什么事情:
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; }
首先获取一个Message,而后把Runnable对象传递给Message的callback变量,返回一个Message;
咱们在文章开头中的Handler的官方文档中提到这么一句话
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue.
那么,这里的callback就是这个Runnable object了!
而后咱们接着看sendMessageAtTime到底作了些啥?关键的代码就在最后一句:
return enqueueMessage(queue, msg, uptimeMillis);
从这个方法名中,咱们能够知道它是让这个消息入列,咱们来看一下它的具体实现:
1 boolean enqueueMessage(Message msg, long when) { 2 if (msg.target == null) { 3 throw new IllegalArgumentException("Message must have a target."); 4 } 5 if (msg.isInUse()) { 6 throw new IllegalStateException(msg + " This message is already in use."); 7 } 8 9 synchronized (this) { 10 if (mQuitting) { 11 IllegalStateException e = new IllegalStateException( 12 msg.target + " sending message to a Handler on a dead thread"); 13 Log.w("MessageQueue", e.getMessage(), e); 14 msg.recycle(); 15 return false; 16 } 17 18 msg.markInUse(); 19 msg.when = when; 20 Message p = mMessages; 21 boolean needWake; 22 if (p == null || when == 0 || when < p.when) { 23 // New head, wake up the event queue if blocked. 24 msg.next = p; 25 mMessages = msg; 26 needWake = mBlocked; 27 } else { 28 // Inserted within the middle of the queue. Usually we don't have to wake 29 // up the event queue unless there is a barrier at the head of the queue 30 // and the message is the earliest asynchronous message in the queue. 31 needWake = mBlocked && p.target == null && msg.isAsynchronous(); 32 Message prev; 33 for (;;) { 34 prev = p; 35 p = p.next; 36 if (p == null || when < p.when) { 37 break; 38 } 39 if (needWake && p.isAsynchronous()) { 40 needWake = false; 41 } 42 } 43 msg.next = p; // invariant: p == prev.next 44 prev.next = msg; 45 } 46 47 // We can assume mPtr != 0 because mQuitting is false. 48 if (needWake) { 49 nativeWake(mPtr); 50 } 51 } 52 return true; 53 }
分析第2行:msg.target,这个target指的是啥呢?咱们这里先暂时无论,后来具体分析Message这个类的时候,咱们会分析到
分析第10行:mQuitting,若是这个变量为true,那么就会抛出一个异常,在后续的分析IntentService的时候,咱们会遇到这个异常,在这里先有个印象;
分析第33-45行:这里就是把消息按照消息的时间顺序进行排列而已,即把消息队列中的消息按照时间进行排序,并无执行真正的入列操做,那何时执行真正的入列操做呢?后面分析Looper这个类的时候,咱们会分析到
1 /** 2 * Handle system messages here. 3 */ 4 public void dispatchMessage(Message msg) { 5 if (msg.callback != null) { 6 handleCallback(msg); 7 } else { 8 if (mCallback != null) { 9 if (mCallback.handleMessage(msg)) { 10 return; 11 } 12 } 13 handleMessage(msg); 14 } 15 }
从方法名称来看,这个方法是用来分发消息的,咱们进入方法里面看一下,首先先判断Message的callback是否为空,这个callback究竟是个啥?跟进去看一下
/*package*/ Runnable callback;
是个Runnable,这里就是咱们在getPostMessage这个方法中提到的把Runnable对象传递给Message的callback变量,也就是说,若是咱们调用Hander的postXX的方法,那么就会把这个Runnable对象赋值给Message的callback变量,那么在上述代码的第五行中,当这个变量不为空的时候,就会调用handleCallback(msg):这个方法去处理消息,
private static void handleCallback(Message message) { message.callback.run(); }
看到这里,你们就明白了,咱们调用Handler 的postXX方法时,能够在这个Runnalble对象的run方法里去执行UI操做了。
接着分析上面代码的else分支,
1 else { 2 if (mCallback != null) { 3 if (mCallback.handleMessage(msg)) { 4 return; 5 } 6 } 7 handleMessage(msg); 8 }
若是Handler的mCallback成员变量若是不为空,那么就调用这个接口的handleMessage方法,不然的话,就走handleMessage(msg)方法,
/** * Subclasses must implement this to receive messages. */ public void handleMessage(Message msg) { }
好了,这下终于到咱们比较熟悉的Handler的处理消息方法上去了,这个方法就是咱们在Handler里处理UI操做的方法了。
本篇只是单独地对Handler这个类分析它的内部实现及对外提供的接口及方法,并无对与Handler紧密相关联的Looer类,MessageQueue类,Message进行分析,目的是为了清晰地对单个封闭的类进行感性的认识以后,再对与之关联的类相互之间的关联调用进行分析;
总结:
1,Handler能够处理 Message及Runnable对象;
2,Handler提供多种构造方法,从而获得与之紧密关联的Looper对象,MessageQueue对象等;
3,Handler提供了两种类型的发送消息的方法,post版本及sendMessage版本
4,Handler提供了重要的dispatchMessage方法,在这个方法中明确是把消息给Runnable对象的run方法仍是给Handler子类的handlMessage方法执行UI操做。