• 关于 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源码反复研读,不然肯定是一脸懵逼。

     

     

     

     

     

     

  • 相关阅读:
    获取代理服务器ip列表的方法
    司机奖励新政策:失去的奖励还能再回来!
    成都Uber优步司机奖励政策(2月24日)
    北京Uber优步司机奖励政策(2月24日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(2月24日)
    成都Uber优步司机奖励政策(2月23日)
    北京Uber优步司机奖励政策(2月23日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(2月23日)
    Android Studio 模拟器启动问题——黑屏 死机 解决方法
    MYSQL使用mysqldump导出某个表的部分数据
  • 原文地址:https://www.cnblogs.com/hankzhouAndroid/p/8733729.html
Copyright © 2020-2023  润新知