经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
「Android」消息驱动Looper和Handler类分析
来源:cnblogs  作者:sunwengang  时间:2018/10/23 9:16:25  对本文有异议

Android系统中的消息驱动工作原理:

1、有一个消息队列,可以往这个消息队列中投递消息;

2、有一个消息循环,不断的从消息队列中取得消息,然后处理。

 

工作流程:

1、事件源将待处理的消息加入到消息队列中,一般是加至队列尾部(优先级高的消息可以加至队列头),事件源提交的消息可以是按键、触摸等物理事件产生的消息,也可以是系统或应用程序发出的消息;

2、处理线程不断的从消息队列头中取出消息并处理。

 

在Android系统中,这些工作主要由LooperHandler实现:

Looper类,用于封装消息循环,并且有一个消息队列;

Handler类,封装消息投递、消息处理等接口。

 

一、Looper类分析

Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,使用Looper.prepare()和Looper.loop()创建了消息队列就可以让消息处理在该线程中完成。

  1. class LooperThread extends Thread
  2. {
  3. public void run()
  4. {
  5. Looper.prepare();
  6. //代码1....
  7. Looper.loop();
  8. //代码2....
  9. }
  10. }

(1)在 Looper.prepare()中,定义一个ThreadLocal对象sT,并构造一个Looper对象设置到调用线程的局部变量sT中。

    ThreadLocal是java中的线程局部变量类(Thread Local Variable),该类有两个关键函数:

  • set:设置调用线程的局部变量
  • get:获取调用线程的局部变量

  因此,prepareh函数会在调用线程的局部变量中设置一个Looper对象。这个调用线程就是LooperThread的run线程。

  1. private Looper(){
  2. //构造一个消息队列
  3. mQueue = new MessageQueue();
  4. //得到当前线程的Thread对象
  5. mThread = Thread.currentThread();
  6. }

  prepare函数中设置了一个Looper对象,对象保存在这个调用线程的局部变量中。而Looper 对象内部封装了一个消息队列。

 

(2)Looper循环

  > 在Loop()方法中,首先通过ThreadLocal的get方法获取创建的Looper对象;

  > 之后取出这个Looper的消息队列  MessageQueue   queue = looper.mQueue; 

  > while循环中,处理消息:

  1. while(true){
  2. Message msg = queue.next();
  3. // 处理i消息,Message对象中有一个target(Handler类型)
  4. // 如果target为空,则退出消息循环
  5. if (msg != null ) {
  6. if (msg.target == null) { return; }
  7. // 调用该消息的Handler,交给他的dispatchMessage函数处理。
  8. msg.target.dispatchMessage(msg);
  9. msg.recyle();
  10. }
  11. }

 

     因此,分析prepare和loop函数后,Looper的作用有:

  1、封装了一个消息队列;  

  2、prepare函数把这个Looper和调用prepare的线程(最终的处理线程)关联在i一起;

  3、处理线程调用loop函数,处理来自消息队列的消息   

    当事件源向Looper发送消息时,消息加到Looper的消息队列。该消息将由和Looper绑定的处理线程来处理

  

 注:Looper、Message、Handler的关系:

  1、Looper中有一个Message队列,存储的时一个个待处理的message;

  2、Message中有一个Handler,用来处理Message。 

 

二、Handler类分析

  Handler中包括的成员:

    Hadler.java:      

  1. final messageQueue mQueue; //Handler中也有一个消息队列
  2. final Looper mLooper;
  3. final Callback mCallback; //i回调用的类

  在Handler的构造函数中,Handler中的消息队列最终会指向Looper的消息队列。

(1)插入消息到Looper消息队列 

  Handler提供了一系列帮助完成创建消息和插入消息队列的函数。

  例如Handler.java中sendMessage发送一个消息,将消息添加到消息队列末尾

  1. public final boolean sendMessage(Message msg) {
  2. return sendMessageDelayed(msg, 0);
  3. }
  4. public final boolean senMessageDelayed(Message msg, long delayMilis){
  5. ......
  6. return senMessage(msg, SystemClock.uptimeMillis() + delayMillis); // 当前时间
  7. }
  8. public boolean sendMessageTime(Message msg, long uptimeMillis) {
  9. boolean sent = false;
  10. MessageQueue queue = mQueue;
  11. if (queue != null) {
  12. msg.target = this; // 将targt设置为自己,然后加入到消息队列
  13. sent = queue.enqueueMessage(msg, uptimeMillis);
  14. }
  15. return sentl
  16. }

   (2)Handler的消息处理

   在loop方法中,如果获得消息后会调用target的dispatchMessage函数,然后将这个消息派发给Handler处理。

   dispatchMessage定义了一套消息处理的优先级机制:

    > Messagu如果自带callback处理,则交给callback处理;

    > Handler如果设置了全局的mCallback,则交给mCallback处理;

    > 如果上述都没有,消息则会被交给Handler子类实现的handleMessage 来处理。(这需要从Handler派生并重载handleMessage函数)   

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号