zoukankan      html  css  js  c++  java
  • 关于 android的消息机制

    引子:

    提到android中消息机制,我相信所有安卓开发者都知道消息机制是用于android的线程间通信,而且都知道如何使用。

    比如下面的用法:

     1     private Handler handler = new Handler() {
     2         @Override
     3         public void handleMessage(Message msg) {
     4             switch (msg.what) {
     5                 case 1:
     6                     String s = msg.getData().getString("time");
     7                     tv_time.setText(s);
     8                     break;
     9             }
    10         }
    11     };
    1                     Message msg = Message.obtain();
    2                     msg.what = 1;
    3                     Bundle bd = new Bundle();
    4                     bd.putString("time", "" + i);
    5            msg.setData(bd);
    6                     handler.sendMessage(msg);

    上面的代码中,能体现出的消息机制中的关键点只有两个:Handler和Message。

    可是,消息机制的完整流程,不仅仅有Handler和Message,还有MessageQueue和Looper。 4个组成部分密切合作,才有了完整的消息机制。

    本文参照了网上大佬的博文,结合自己的代码跟踪,给读者提供探索消息机制的思路。

    Handler,Message,MessageQueue,Looper的关系:

    参照大佬的博文:https://www.cnblogs.com/ryanleee/p/8204450.html 中的插图(膜拜大佬!)

    四者的关系如图所示:

    首先要说明四个部分的作用;

    Message:消息本体类。创建一个Message对象,设置一系列参数,然后交由Handler进行发送。

    MessageQueue:消息队列类。存放Message的队列,handler发送的消息,并不会立即执行,而是都会先存放在这个队列中。

    Looper:消息循环类。用于管理MessageQueue,进行无限循环,将队列中的消息进行顺序执行。

    Handler:消息机制的主要接口类,由Handler来发送消息,并且在创建handler时可以重写handlerMessage来预定义可能会执行的操作。

    (这里必须先说明一点,因为图中并没有表现的太明白: 一个线程,对应 一个Handler,对应一个Looper,对应一个MessageQueue,对应多个Message。所以,在一个线程里面,handler,looper以及messageQueue都是唯一的);

     

    如果以handler发送message为起点,那么图里面的程序执行流程就是:

    1)handler发送message对象

    2)MessageQueue接收到message,然后将它加入队列

    3)Looper进行消息队列的无限循环,每次弹出一个消息

    4)被弹出的消息,会交给Handler,让handler执行handlerMessage。 

    如果理解了上面的4个步骤,那请看下文。

     

    代码追踪详解(请对照SDK源码进行阅读,伸手党们可以止步了···):

    从Handler的sendMessage开始跟踪:

    跟踪sendMessageDelayed方法。

    跟踪sendMessageAtTime方法:

     

    在这里,就接触到了MessageQueue,再跟踪,enqueueMessage方法。

    能看到,messageQueue将msg加入到了队列中。

    ok,这就是handler,message,以及messageQueue之间的关系的代码依据。

     

    ================================================================

    那么,handler类里面的mQueue对象是怎么来的呢?请看图:

    跟踪mQueue对象,可以发现,这个mQueue是来自looper对象。

    那这个Looper又是怎么来的呢?来自Looper类的静态方法,它可以拿到当前线程中的looper对象。

     

    OK,以上,就是handler发送消息,到messageQueue收到消息的过程。

    ==========================================================================

     那么,Looper进行无限循环,到handler.handleMessage的代码依据呢?

    请看Looper的loop方法:

    两个标记了红色的地方,一个是获取当前线程的looper中的messageQueue,另一个是在无限循环中,执行消息(queue.next()每次取出一个消息)的过程。

    上面,用queue.next()每次取出了一个消息,那么这些消息如何执行的?请看下图(还是在Looper类中):

    这里能看到的   msg的target,就是一个Handler对象。 这里的代码,执行了handler的dispatchMessage(msg).

    那么,就跟踪这个dispatchMessage(代码在Handler内部):

    这段代码解读如下(handler执行handleMessage也是有一个优先级顺序的):

    msg是可以自带callback的,如果有自带,那么优先执行它自带的callback;
    如果msg没有自带callback,那么检查handler的mCallback是不是存在,如果存在,就执行它。
    如果以上都不成立,那就执行handler自身的handlerMessage方法(这个方法通常用在创建Handler的时候进行覆写)。

     OK,以上就是Looper进行消息循环,直到消息最后执行过程的代码依据。

     再次提醒,此章节需要对照SDK源码反复研读,不然肯定是一脸懵逼。

     

     

     

     

     

     

  • 相关阅读:
    事务管理
    QQ邮箱开启SMTP方法如何授权
    基于JavaMail的Java邮件发送:简单邮件发送
    Spring MVC 响应视图(六)
    Spring MVC 数据绑定 (四)
    Spring MVC Spring中的Model (五)
    Spring MVC 拦截器 (十)
    Spring MVC 异常处理 (九)
    Java 骚操作--生成二维码
    Java MD5校验与RSA加密
  • 原文地址:https://www.cnblogs.com/hankzhouAndroid/p/8733729.html
Copyright © 2011-2022 走看看