Android处理程序:Handler Looper Message源码研究

移动开发 Android
Looper是消费者,Handler是生产者(同时Looper消费后,也会通知Handler),MessageQueue是消息队列,队列的实现方式是链表,Message是链表的一个节点。 我们的程序基本上之和Handler打交道。

线程Thread的线程变量ThreadLocal中,存放着这个线程的Looper;Looper在初始化时,会新建一个消息队列MessageQueue,之后Looper进入一个死循环,等待从消息队列MessageQueue取得消息Message(Looper是消费者),没有消息时会阻塞;

我们程序中的Handler,会通过sendMessage或post方法,往MessageQueue中添加消息时,添加的这个Message,会记录他是属于哪个Handler发出的,同时根据message.when,决定新添加的这个Message在Queue中的位置,MessageQueue中只有一个当前的Message,队列关系是通过Message中的prev,next维护的,Message是一个链表的节点;

添加消息后,消费者Looper取得Message,并调用建立Message的Hander的dispatchMessage方法。

咋一看好像Handler即sendMessage,又handlerMessage,事情还是只有一个线程在做事情。

但是后来想想,明白了这样设计的必要性。

因为这个***的线程一般而言,都是mainUI线程,如果你有个可以分成多个小任务的任务要处理,你没有使用Handler,直接执行,也许系统忙于处理你这个任务,而无法及时响应用户事件,从而导致ANR的抛出。

如果你把你的任务拆成几个小任务,用Handler来实现,那么系统就可以把你的小任务推到后面来处理,抽出时间来响应用户操作。

如果真的有大任务,一般式需要另外线程去处理,或者开启Service。

一个在新线程中使用handler例子,我们来分析下源码

Java代码

new Thread(new Runnable() { 
@Override public void run() { 
Handler handler; 
//1、初始化Looper 
Looper.prepare(); 
//2、绑定handler到CustomThread实例的Looper对象、定义处理消息的方法 
handlernew Handler() { 
@Override public void handleMessage(Message msg) { 

}; 
// 3、发送消息 
handler.sendMessage(new Message()); 
handler.post(new Runnable()) 
handler.obtainMessage(1, "hello").sendToTarget(); 
//4、启动消息循环 
Looper.loop(); 

}).start(); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

1 Java代码

public static final void prepare() { 
if (sThreadLocal.get() != null) { // 每个线程,只能有一个Looper对象 
throw new RuntimeException("Only one Looper may be created per thread"); 

// 如果当前线程没有Looper,新建一个,构造函数是private的 
sThreadLocal.set(new Looper()); 

private Looper() { 
mQueue = new MessageQueue(); // 建立消息队列 
mRun = true
mThread = Thread.currentThread(); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

2 Java代码

public Handler(){ 
mLooper = Looper.myLooper(); // 取得当前线程的Looper,如果抛异常 
if (mLooper == null) { 
throw new RuntimeException( 
"Can't create handler inside thread that has not called Looper.prepare()"); 

mQueue = mLooper.mQueue; // 取得消息队列 
mCallback = null

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

3 Java代码

//不管调用哪个方法,最终执行的是 
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; 

final boolean enqueueMessage(Message msg, long when) { 
if (msg.when != 0) { 
throw new AndroidRuntimeException(msg 
" This message is already in use."); 

if (msg.target == null && !mQuitAllowed) { 
throw new RuntimeException("Main thread not allowed to quit"); 

synchronized (this) { 
if (mQuiting) { 
RuntimeException e = new RuntimeException( 
msg.target + " sending message to a Handler on a dead thread"); 
Log.w("MessageQueue", e.getMessage(), e); 
return false
else if (msg.target == null) { 
mQuiting = true

msg.when = when; 
Message p = mMessages; 
// 之前没有其他消息了,MessageQueue中当前消息mMessages 就是传递进来的msg 
if (p == null || when == 0 || when < p.when) {  
msg.next = p; 
mMessages = msg; 
this.notify(); // 唤醒  
else {  
// 之前有其他消息了,将传递的msg放到适合的位置,根据when  
Message prev = null 
while (p != null && p.when <= when) {  
prev = p;  
p = p.next;  
 
msg.next = prev.next;  
prev.next = msg;  
this.notify(); // 唤醒  
 
 
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.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.

4 Java代码

public static final void loop() { 
Looper me = myLooper(); 
MessageQueue queue = me.mQueue; 
while (true) { // 死循环 
Message msg = queue.next(); // 当队列中没有消息时会阻塞 
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 
); 
// 调用消息发出者的dispatchMessage,这里msg.target是我们sendMessage的handler 
msg.target.dispatchMessage(msg); 
if (me.mLogging!= null) me.mLogging.println( 
"<<<<< Finished to " + msg.target + " " 
+ msg.callback); 
msg.recycle(); 



final Message next() { 
boolean tryIdle = true
while (true) { 
synchronized (this) { 
// 没有消息的或,会阻塞 
try { 
if (mMessages != null) { 
if (mMessages.when-now > 0) { 
Binder.flushPendingCommands(); 
this.wait(mMessages.when-now); 

else { 
Binder.flushPendingCommands(); 
this.wait(); 


catch (InterruptedException e) { 




  • 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.

总结

Handler作用:

1. 执行计划任务

2. 线程间通信

一个handler,只能接收到自己发出的message。handler实例与消息Message处理是关联的,发送和接受要匹配

Handler操作队列,主要是在子线程操作主线程的消息队列

Handler是实现异步的一种方式,用法是在主线程中建立Handler,(主线程中的Handler不用掉Looper.prepare);

在子线程(耗时操作)任务完成后sendMessage,这个Message会发送到主线程的消息队列中,主线程Handler的重写dispatchMessage方法,做新线程任务完成后的事情,大部分是更新UI。

责任编辑:佚名 来源: Iteye
相关推荐

2016-10-21 13:03:18

androidhandlerlooper

2014-05-22 15:07:44

Android消息处理机制Looper

2014-05-22 15:41:59

Android消息处理机制Looper

2014-05-22 15:48:50

Android消息处理机制Looper

2014-05-22 15:04:00

Android消息处理机制Looper

2014-05-22 15:38:27

Android消息处理机制Looper

2014-05-22 15:00:16

Android消息处理机制Looper

2014-05-22 14:57:28

Android消息处理机制Looper

2014-05-22 15:15:53

Android消息处理机制Looper

2014-05-22 15:18:25

Android消息处理机制Looper

2014-05-22 15:33:31

Android消息处理机制Looper

2014-05-22 15:45:58

Android消息处理机制Looper

2013-03-28 16:12:12

Message机制应用

2024-05-22 08:35:41

2012-12-28 14:32:34

Android开发Handler异步处理

2011-04-28 11:01:40

Android消息处理LooperHandler

2013-04-11 12:40:16

Android消息机制

2021-08-12 16:28:10

AndroidHandleLooper

2022-04-07 08:30:57

AMQP协议RabbitMQ客户端源码

2017-08-07 20:18:11

Android线程handler
点赞
收藏

51CTO技术栈公众号