的消息循环机制主要先关的类有:
- Handler
- Looper
- Message
- MessageQueue
- ActivityThread
实际上
应用程序启动的时候,会创建一个UI线程,然后该线程关联一个消息队列,相关操作封装一个个消息放入队列中,主线程会不断循环从队列中取出消息进行分发处理。
为什么用Handler
大家都知道,Android规定【访问UI只能在主线程中进行】,如果在子线程中访问UI,程序会出现异常。
throw new CalledFromWrongThreadException("only the original thread that created a view hierarchy can touch its views.");
- 1
- 1
所以只能在主线程中访问UI,但是Android又不建议在主线程中做耗时操作,比如IO操作、网络请求等操作,否则容易引起程序无法响应(ANR)。所以想这些耗时操作,都会放到其他的线程中进行处理,但是非UI线程又无法操作UI,所以 Handler 就派上用场了。
Handler的作用就是将一个任务切换到另外一个线程中执行。而我们主要用它来 更新UI 。
Handler的基本使用
先来看看Handler的基本使用。
它的使用方法分为两套: “post”方法和“send”方法。private Handler handler2 = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { return false; } });
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 1: testview.setText("处理完毕"); break; default: break; } } };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
new Thread(){ @Override public void run() { // 一些耗时的操作 handler.sendEmptyMessage(1); } }.start();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
handler.post(new Runnable() { @Override public void run() { testview.setText("post"); } }); handler.postDelayed(new Runnable() { @Override public void run() { testview.setText("postDelayed"); } }, 5000);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
send 系列有 7 个方法:
/** * 1. 发送一个消息 */ public final boolean sendMessage(Message msg){ return sendMessageDelayed(msg, 0); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
/** * 2. 发送一个空消息 */ public final boolean sendEmptyMessage(int what){ return sendEmptyMessageDelayed(what, 0); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
/** * 3. 定时发送一个消息 */ public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageAtTime(msg, uptimeMillis); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
/** * 4. 延迟发送一个空的消息 * 内部调用了 sendMessageDelayed() 方法 */ public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
/** * 5. 发送一个消息到消息队列的头部 */ 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); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
/** * 6. 定时发送一个消息 */ 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); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
/** * 7. 延迟delayMillis时间发送一个消息 */ public final boolean sendMessageDelayed(Message msg, long delayMillis){ if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
通过以上代码可以发现,重载方法相互调用,最终都是调用了enqueueMessage()方法。
post 系列有 5 个方法:
/** * 1. */ public final boolean post(Runnable r){ return sendMessageDelayed(getPostMessage(r), 0); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
/** * 2. */ public final boolean postDelayed(Runnable r, long delayMillis){ return sendMessageDelayed(getPostMessage(r), delayMillis); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
/** * 3. */ public final boolean postAtTime(Runnable r, long uptimeMillis){ return sendMessageAtTime(getPostMessage(r), uptimeMillis); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
/** * 4. */ public final boolean postAtFrontOfQueue(Runnable r){ return sendMessageAtFrontOfQueue(getPostMessage(r)); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
/** * 5. */ public final boolean postAtTime(Runnable r, Object token, long uptimeMillis){ return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
从以上代码中可以看出,post的这几个方法都是调用的send的先关方法。只不过 通过getPostMessage()的几个重载方法,将Runnable封装成了Message 。
来看看getPostMessage的重载方法:
/** * 设置消息对象的callback, 返回Message对象 * 当调用dispatchMessage()方法的时候,判断Message的callback是否为空,不为空时,调用callback的run()方法。 */ private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; } /** * 将Runnable和Object封装成一个Message对象返回。 */ private static Message getPostMessage(Runnable r, Object token) { Message m = Message.obtain(); m.obj = token; m.callback = r; return m; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
一共有两个,都是通过 Message.obtain() 方法获取一个消息对象,然后重新对内部变量赋值,然后返回该Message对象。
我们先记下这个方法,稍后进行探索。
综上,不管是post方法,还是send方法,最后都牵扯到 enqueueMessage 这样一个方法。
/** * 将message添加到消息队列 */ private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; // 这里将message的target对象赋为handler if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
该方法内部,将message的target赋值为当前Handler对象,可见 target是Handler类型的对象 。
最后调用了queue.enqueueMessage()对象。
queue是MessageQueue类型的变量 ,表示一个消息队列。我们先不管该变量什么时候初始化的,先看看这个方法。
Message mMessages; /** * 消息入队操作 */ boolean enqueueMessage(Message msg, long when) { // ... synchronized (this) { // ... msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; //当mMessage为空 或者 when是0 后者when小于对头的when值时,将当前msg作为对头。 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 { // 当msg添加到队列中间。 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; } // ... } return true; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
从上面代码可以看出,消息队列实际上是通过 单链表 的结构来实现的。其内部逻辑也好懂,就是通过对when和当前对头指针的一些判断逻辑,进而将参数中的message添加到单单链表中。
说到这里,进行一个小总结:
当我们使用Handler的时候,通过post或者send的一些列方法时,实际上是把一个Message(消息)添加到MessageQueue(消息队列)中去。Looper
Looper可以称之为“消息循环”。我们将消息放到消息队列之后,还需要通过Looper从队列中取出消息进行处理。
主线程也就是ActivityThread,它被创建的时候,会调用 ActivityThread.main() 方法。
ActivityThread.java 的部分源码:
static Handler sMainThreadHandler; // set once in main() public static void main(String[] args) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); //... Process.setArgV0(""); //初始化当前线程为looper Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); //开始运行线程中的 消息队列 -- message queue Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
主要代码是这两句:
-
Looper.prepareMainLooper();
-
Looper.loop();
这又牵涉到了Looper.java类。
接着往下看。
先把Looper类中的先关代码贴出来:
// sThreadLocal.get() will return null unless you've called prepare(). static final ThreadLocalsThreadLocal = new ThreadLocal (); private static Looper sMainLooper; // guarded by Looper.class final MessageQueue mQueue; final Thread mThread;
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
//系统调用此方法,初始化当前线程为looper,作为一个应用程序的主looper。 public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) {//一个线程只允许存在一个looper对象。 throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
//Looper构造函数 -- 私有化 private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); } //返回绑定到当前线程上的Looper对象 public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
通过以上代码,我们可以看出:
-
Looper类中维护一个消息队列和一个ThreadLocal类型的对象。
-
Looper的构造函数是private类型,私有化的。 所以只能通过 prepare(boolean) 方法来进行初始化。
-
在Looper的构造函数中对MessageQueue进行了初始化。
- 一个线程只允许存在一个looper对象。否则会出现运行时异常。
当ActivityThread.main方法准备好Looper之后,此时队列就和线程关联了起来。,然后调用了Looper的loop()方法。
final MessageQueue mQueue; final Looper mLooper; final Callback mCallback;
- 1
- 2
- 3
- 1
- 2
- 3
public static void loop() { final Looper me = myLooper(); if (me == null) {//如果me是null,则表示没有调用prepare()方法。 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue;// 1. 获取消息队列 // ... for (;;) { // 2. 死循环--消息循环 Message msg = queue.next(); // 3. 获取消息 (从消息队列中阻塞式的取出Message) if (msg == null) { // No message indicates that the message queue is quitting. return; } // ... // Message对象内部有一个Handler对象target。故,实际上调用的handler的dispatchMessage // 故,实际上调用的handler的dispatchMessage(msg)方法进行分发。 msg.target.dispatchMessage(msg); // 4. 分发处理消息 if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // ... msg.recycleUnchecked();// 5. 回收消息 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
loop方法实际上建立了一个死循环,一直从消息队列中读取消息,然后调用Message的target对象,实际上就是Handler对象的dispatchMessage(msg) 方法进行处理。
(上面提到了,target实际上是Handler类型的对象)
接着来看Handler.dispatchMessage(msg)
/** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) {// 当message对象中Runnable类型的callback不为空时 handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); // 调用重写的方法 } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
当我们使用Handler.postxx()之类的方法时,会传入一个Runnable对象,这种情况下,“创建”的Message的callback变量不是null,dispatchMessage方法里面调用 handleCallback(msg) ,然后就调用了run()方法;
// 调用runnable类型的run()方法 private static void handleCallback(Message message) { message.callback.run(); }
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
如果不是采用Handler.postxxx()之类的方法,也即callback变量为null,dispatchMessage方法里面调用handlerMessage(msg);
// 实现该接口时,重写该方法。 public interface Callback { public boolean handleMessage(Message msg); } /** * 使用Handler的时候,会重写该方法。 */ public void handleMessage(Message msg) { }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
通过dispatchMessage(msg)方法的分发处理,就可以将事件在主线程中处理。
Handler的构造函数
上面提到,handler的7+5个方法都是调用的 MessageQueue.enqueueMessage() 方法把消息添加到消息队列中去。
实际上消息队列就是在Handler的构造函数中 获取 的。
看看它的构造方法:
/** * 无参构造函数 */ public Handler() { this(null, false); } /** * Callback就是那个接口 */ public Handler(Callback callback) { this(callback, false); } /** * 通过looper对象构造 */ 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); } /** * 进行一些初始化操作 * 可以看出当使用无参的Handler的时候,mCallback对象是null。 */ public Handler(Callback callback, boolean async) { // ... mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue;// 获取Looper中保存的消息队列 mCallback = callback; mAsynchronous = async; } /** * 指定Looper对象的构造函数很简单 */ public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
我们最常用的就是无参的构造。
无参构造又调用了 public Handler(Callback callback, boolean async) 这个方法。 该方法内部调用了Looper类的 myLooper() 方法。 然后又从looper中取出messagequeue为Handler里的mQueue 赋值。
综上,当调用Handler的send或者post相关方法时,把消息添加进的消息队列是从Looper对象中获取的。而Looper的消息队列是new出来的,是在ActivityThread.main()中调用Looper.prepareMainLooper(),然后调用Looper.prepare(boolean)方法,在这个方法里面new了一个Looper对象,而Looper的私有构造函数中正好创建了一个消息队列。
此时,【消息产生->添加到消息队列->处理消息】 这个流程就走通了。
Message.obtain()
回过头来看getPostMessage()的两个重载方法,内部调用了 Message.obtain() 方法。
该方法用来获取一个Message对象,而不是直接new一个Message。
// Message采用链式存储结构,内部存储指向下一个message的“指针” Message next; private static final Object sPoolSync = new Object(); // private static Message sPool; // private static int sPoolSize = 0; //消息池大小 /** * 直接从message池中返回一个对象,在多数情况下,都不需要重新new一个对象, * 从而节省了开销。 */ public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
看到这段代码,就发现一个“池”的概念。原来android使用了类似于“线程缓冲池”之类的“消息池”,用来保存一些处理完毕不用的Message对象,以便于下次使用时可以直接从池中获取,而不是直接创建一个新的message,从而节省了内存开销。当池中没有时,才回去new一个新的Message返回。
那既然有从池中获取的方法,当然也要有将对象放入池中的方法。
在Message类中有 recycler() 和 recyclerUnchecked() 两个方法。
/** * 将message对象回收 */ public void recycle() { if (isInUse()) { //是否还在使用 if (gCheckRecycle) { throw new IllegalStateException("This message cannot be recycled because it " + "is still in use."); } return; } recycleUnchecked(); } /** * 重置状态,将消息放到消息池中 */ void recycleUnchecked() { // Mark the message as in use while it remains in the recycled object pool. // Clear out all other details. flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
总结
-
程序启动的时候,主线程会创建一个Looper对象。Looper对象内部维护一个MessageQueue,然后调用loop()方法循环去读取消息。
-
初始化Handler的时候,在Handler的构造函数内部,会获取当前线程的Looper对象,进而获取MessageQueue对象。由此可见,想要操作UI的Handler必须在主线程中创建。否则会提示你:【”Can’t create handler inside thread that has not called Looper.prepare()”】
-
调用Handler的先关方法时,会获取Message对象,将消息对象的target指向当前handler对象,然后放到消息队列中。
-
loop()工作中,会从消息队列中获取一个个的消息,调用handle的dispatchMessage(msg)分发处理。
-
Message内部维护一个消息池,用来回收缓存message对象。
-
Looper相当于一个发动机,MessageQueue相当于流水线,Message相当于一个个的物品,而Handler就相当于工人。