Handler Looper Message源码研究
概述
Looper是消费者,Handler是生产者,MessageQueue是消息队列,队列的实现方式是链表,Message是链表的一个节点。
线程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例子,我们来分析下源码
Java代码- 1.new Thread(new Runnable() {
- 2. @Override public void run() {
- 3. Handler handler;
- 4. //1、初始化Looper
- 5. Looper.prepare();
- 6. //2、绑定handler到CustomThread实例的Looper对象、定义处理消息的方法
- 7. handler= new Handler() {
- 8. @Override public void handleMessage(Message msg) {
- 9. }
- 10. };
- 11. // 3、发送消息
- 12. handler.sendMessage(new Message());
- 13. handler.post(new Runnable())
- 14. handler.obtainMessage(1, "hello").sendToTarget();
- 15. //4、启动消息循环
- 16. Looper.loop();
- 17. }
- 18.}).start();
- new Thread(new Runnable() {
- @Override public void run() {
- Handler handler;
- //1、初始化Looper
- Looper.prepare();
- //2、绑定handler到CustomThread实例的Looper对象、定义处理消息的方法
- handler= new 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
Java代码- 1.public static final void prepare() {
- 2. if (sThreadLocal.get() != null) { // 每个线程,只能有一个Looper对象
- 3. throw new RuntimeException("Only one Looper may be created per thread");
- 4. }
- 5. // 如果当前线程没有Looper,新建一个,构造函数是private的
- 6. sThreadLocal.set(new Looper());
- 7.}
- 8.private Looper() {
- 9. mQueue = new MessageQueue(); // 建立消息队列
- 10. mRun = true;
- 11. mThread = Thread.currentThread();
- 12.}
- 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();
- }
复制代码 2
Java代码- 1.public Handler(){
- 2. mLooper = Looper.myLooper(); // 取得当前线程的Looper,如果抛异常
- 3. if (mLooper == null) {
- 4. throw new RuntimeException(
- 5. "Can't create handler inside thread that has not called Looper.prepare()");
- 6. }
- 7. mQueue = mLooper.mQueue; // 取得消息队列
- 8. mCallback = null;
- 9.}
- 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;
- }
复制代码 3
Java代码- 1.//不管调用哪个方法,最终执行的是
- 2.public boolean sendMessageAtTime(Message msg, long uptimeMillis){
- 3. boolean sent = false;
- 4. // 取得消息队列
- 5. MessageQueue queue = mQueue;
- 6. if (queue != null) {
- 7. msg.target = this; // 消息发出着是自己
- 8. sent = queue.enqueueMessage(msg, uptimeMillis); // 添加到消息队列中
- 9. }
- 10. else {
- 11. RuntimeException e = new RuntimeException(
- 12. this + " sendMessageAtTime() called with no mQueue");
- 13. Log.w("Looper", e.getMessage(), e);
- 14. }
- 15. return sent;
- 16.}
- 17.final boolean enqueueMessage(Message msg, long when) {
- 18. if (msg.when != 0) {
- 19. throw new AndroidRuntimeException(msg
- 20. + " This message is already in use.");
- 21. }
- 22. if (msg.target == null && !mQuitAllowed) {
- 23. throw new RuntimeException("Main thread not allowed to quit");
- 24. }
- 25. synchronized (this) {
- 26. if (mQuiting) {
- 27. RuntimeException e = new RuntimeException(
- 28. msg.target + " sending message to a Handler on a dead thread");
- 29. Log.w("MessageQueue", e.getMessage(), e);
- 30. return false;
- 31. } else if (msg.target == null) {
- 32. mQuiting = true;
- 33. }
- 34.
- 35. msg.when = when;
- 36. Message p = mMessages;
- 37. // 之前没有其他消息了,MessageQueue中当前消息mMessages 就是传递进来的msg
- 38. if (p == null || when == 0 || when < p.when) {
- 39. msg.next = p;
- 40. mMessages = msg;
- 41. this.notify(); // 唤醒
- 42. } else {
- 43. // 之前有其他消息了,将传递的msg放到适合的位置,根据when
- 44. Message prev = null;
- 45. while (p != null && p.when <= when) {
- 46. prev = p;
- 47. p = p.next;
- 48. }
- 49. msg.next = prev.next;
- 50. prev.next = msg;
- 51. this.notify(); // 唤醒
- 52. }
- 53. }
- 54. return true;
- 55.}
- //不管调用哪个方法,最终执行的是
- 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;
- }
复制代码 4
Java代码- 1.public static final void loop() {
- 2. Looper me = myLooper();
- 3. MessageQueue queue = me.mQueue;
- 4. while (true) { // 死循环
- 5. Message msg = queue.next(); // 当队列中没有消息时会阻塞
- 6. if (msg != null) {
- 7. if (msg.target == null) { // 消息没有发送者时,退出消息循环
- 8. // No target is a magic identifier for the quit message.
- 9. return;
- 10. }
- 11. if (me.mLogging!= null) me.mLogging.println(
- 12. ">>>>> Dispatching to " + msg.target + " "
- 13. + msg.callback + ": " + msg.what
- 14. );
- 15. // 调用消息发出者的dispatchMessage,这里msg.target是我们sendMessage的handler
- 16. msg.target.dispatchMessage(msg);
- 17. if (me.mLogging!= null) me.mLogging.println(
- 18. "<<<<< Finished to " + msg.target + " "
- 19. + msg.callback);
- 20. msg.recycle();
- 21. }
- 22. }
- 23.}
- 24.
- 25.final Message next() {
- 26. boolean tryIdle = true;
- 27.
- 28. while (true) {
- 29.
- 30. synchronized (this) {
- 31. // 没有消息的或,会阻塞
- 32. try {
- 33. if (mMessages != null) {
- 34. if (mMessages.when-now > 0) {
- 35. Binder.flushPendingCommands();
- 36. this.wait(mMessages.when-now);
- 37. }
- 38. } else {
- 39. Binder.flushPendingCommands();
- 40. this.wait();
- 41. }
- 42. }
- 43. catch (InterruptedException e) {
- 44. }
- 45. }
- 46. }
- 47.}
- 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) {
- }
- }
- }
- }
复制代码 总结
Handler作用:
1. 执行计划任务
2. 线程间通信
一个handler,只能接收到自己发出的message。handler实例与消息Message处理是关联的,发送和接受要匹配
Handler操作队列,主要是在子线程操作主线程的消息队列
Handler是实现异步的一种方式,用法是在主线程中建立Handler,(主线程中的Handler不用掉Looper.prepare);
在子线程(耗时操作)任务完成后sendMessage,这个Message会发送到主线程的消息队列中,主线程Handler的重写dispatchMessage方法,做新线程任务完成后的事情,大部分是更新UI。 |