博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android之MessageQueue、Looper、Handler与消息循环
阅读量:6910 次
发布时间:2019-06-27

本文共 3582 字,大约阅读时间需要 11 分钟。

在android的activity中有各种各样的事件,而这些事件最终是转换为消息来处理的。android中的消息系统涉及到:

 *  消息发送
 *  消息队列
 *  消息循环
 *  消息分发
 *  消息读取
  消息对应的重要类有MessageQueue、Looper、Handler,它们分别对应着消息队列、消息循环和消息处理。

 

Handler类:

Handler主要用来发送消息和处理消息。每个handler实例都对应着一个线程和该线程的消息队列。
当你创建一个handler对象时,该handler对象就属于创建它的线程,并和该线程的消息队列绑定,比如在主线程中创建handler对象,那么该handler就只属于主线程,并且和主线程的消息队列绑定。(当然,每个线程都有自己的消息队列,在android中,消息队列是针对与线程的)。这样,该handler就可以发送消息到该消息队列并且处理该消息队列的消息了。
当执行一些费时的操作时,比如需要远程网络访问、下载等操作时,一般情况下都会启动一个新的线程去操作。而不会放在ui线程去做,这样可以防止android的5秒无相应导致的ANR异常。子线程中返回的结果怎样更新到ui线程呢,这时就可以通过handler来处理了。可以在主线程中定义handler,然后通过主线程handler把子线程中的消息发送到主线程对应的消息队列。在主线程中通过handler.handlerMessage就可以处理消息了,并更新到ui了。
我们刚才说过,Handler主要是用来发送、处理消息的。那么消息循环、队列是在哪里管理的。答案是:Looper、MessageQueue中。

Looper类:

looper类主要用来开启线程的消息循环。默认情况下,系统在启动的时候会为主线程创建消息循环。其他新创建的线程则没有,
如果需要,可以在该线程内调用Looper.prepare()来启用looper对象,然后调用Looper.loop()进入消息循环。
这样该线程就具有消息循环机制了,比如:

class LooperThread extends Thread {          public Handler mHandler;                    public void run() {              Looper.prepare();                            mHandler = new Handler() {                  public void handleMessage(Message msg) {                      // process incoming messages here                  }              };                            Looper.loop();         }   }

实际上消息队列也是在Looper中创建的,看下Looper的loop()方法,这个方法就是用来做消息循环用的。

 

public static final void loop() {           Looper me = myLooper(); //获得当前线程的Looper对象           MessageQueue queue = me.mQueue;  //获得当前线程的消息队列          while (true) { //条件为true、一直循环执行。消息循环              Message msg = queue.next(); // might block                //if (!me.mRun) {              //    break;               //}              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.whclearForRecycleat                           );                   msg.target.dispatchMessage(msg); //消息分发                  if (me.mLogging!= null) me.mLogging.println(                           "<<<<< Finished to    " + msg.target + " "                           + msg.callback);                   msg.recycle(); //消息已经分发出去,对消息进行回收处理               }           }       }

 

我们再来看Handler的构造函数,在Handler的构造函数中获得当前线程的Looper对象、和消息队列。消息队列也是从looper中获得的,刚才我们说过。

 

public Handler() {           if (FIND_POTENTIAL_LEAKS) {               final Class
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()); } } //在Handler的构造函数中获得当前线程的Looper对象、和消息队列。消息队列也是从looper中获得的 mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = null; }

 

在handler中还有一些重要的方法:

 

handleMessage(Message)   //处理消息

dispatchMessage(Message)  //分发消息

sendMessage(Message)   //发送消息

 

到这里我们大致可以了解android中的消息流程大概是这样的:

Handler获得当前线程的Looper、MessageQueue,并且发送消息到MessageQueue中。 Looper对消息做循环,并通过 msg.target.dispatchMessage来分发消息(target应该就是handler)。然后Handler.handlerMessage处理消息。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载地址:http://vxycl.baihongyu.com/

你可能感兴趣的文章
微信公众平台企业号回调模式的URL验证
查看>>
平台常用函数介绍
查看>>
公司讲座
查看>>
惆怅,诸事不顺
查看>>
Lambda架构与推荐在电商网站实践
查看>>
Docker Swarm与Apache Mesos的区别
查看>>
消息中间件保证消息一致性解决方案
查看>>
java内嵌浏览器DJNativeSwing
查看>>
Php学习
查看>>
寓意很深刻的故事
查看>>
Confluence 6 权限概述
查看>>
Android小白的探索:2D绘图之Android简易版Microsoft Visio学习之路 三、装饰者模式...
查看>>
现代操作系统--引论
查看>>
Unix Study之--AIX安装和配置SSH
查看>>
C++ priority_queue用法(大顶堆,小顶堆)
查看>>
带返回值的python多级菜单
查看>>
Linux中~/.是什么意思
查看>>
MySql-Binlog协议详解-流程篇
查看>>
Effective Java 学习笔记(第57条:只针对异常的情况才使用异常)
查看>>
Simple-Spring-Memcached深入研究一
查看>>