• Android之Handler(上)


    Handler机制的相关类

    Hanlder:发送和接收消息 Looper:用于轮询消息队列,一个线程只能有一个Looper Message: 消息实体
    MessageQueue: 消息队列用于存储消息和管理消息

    创建Looper

    在这里插入图片描述
    在ActivityThread中的main方法中为我们prepare了在这里插入图片描述
    在这里插入图片描述
    prepare有两个重载的方法,主要看 prepare(boolean quitAllowed) quitAllowed的作用是在创建MessageQueue时标识消息队列是否可以销毁, 主线程不可被销毁,下面有介绍
    在这里插入图片描述

    创建MessageQueue以及Looper与当前线程的绑定
    在这里插入图片描述
    MessageQueue的构造方法
    在这里插入图片描述

    Looper.loop()

    同时是在main方法中 Looper.prepareMainLooper() 后Looper.loop(); 开始轮询
    在这里插入图片描述

    创建Handler

    最常见的创建handler
    在这里插入图片描述
    在内部调用 this(null, false);
    在这里插入图片描述
    Looper.myLooper();
    在这里插入图片描述
    sThreadLocal.get() will return null unless you’ve called prepare(). 这句话告诉我们get可能返回null 除非先调用
    prepare()方法创建Looper。在前面已经介绍了

    创建Message

    可以直接new Message 但是有更好的方式 Message.obtain。因为可以检查是否有可以复用的Message,用过复用避免过多的创建、销毁Message对象达到优化内存和性能的目地
    在这里插入图片描述
    创建Message的时候可以通过 Message.obtain(Handler h) 这个构造方法绑定。当然可以在 在Handler 中的enqueueMessage()也绑定了,所有发送Message的方法都会调用此方法入队,所以在创建Message的时候是可以不绑定的
    在这里插入图片描述

    Handler发送消息

    Handler发送消息的重载方法很多,但是主要只有2种。 sendMessage(Message) sendMessage方法通过一系列重载方法的调用,sendMessage调用sendMessageDelayed,继续调用sendMessageAtTime,继续调用enqueueMessage,继续调用messageQueue的enqueueMessage方法,将消息保存在了消息队列中,而最终由Looper取出,交给Handler的dispatchMessage进行处理
    我们可以看到在dispatchMessage方法中,message中callback是一个Runnable对象,如果callback不为空,则直接 调用callback的run方法,否则判断mCallback是否为空,mCallback在Handler构造方法中初始化,在主线程通直接 通过无参的构造方法new出来的为null,所以会直接执行后面的handleMessage()方法。
    在这里插入图片描述

    Handler处理消息

    在handleMessage(Message)方法中,我们可以拿到message对象,根据不同的需求进行处理,整个Handler机制的流程就结束了。

    小结

    handler.sendMessage 发送消息到消息队列MessageQueue,然后looper调用自己的loop()函数带动MessageQueue从而轮询messageQueue里面的每个Message,当Message达到了可以执行的时间的时候开始执 行,执行后就会调用message绑定的Handler来处理消息。大致的过程如下图所示
    在这里插入图片描述
    handler机制就是一个传送带的运转机制。
    1)MessageQueue就像履带。
    2)Thread就像背后的动力,就是我们通信都是基于线程而来的。
    3)传送带的滚动需要一个开关给电机通电,那么就相当于我们的loop函数,而这个loop里面的for循环就会带着不断 的滚动,去轮询messageQueue
    4)Message就是 我们的货物了。

  • 相关阅读:
    基于APB与I2C的多主多从架构设计 - Function Description
    开源浪潮下的共创与挑战:开发者视角的深度剖析
    Qt/C++开源作品45-CPU内存显示控件/和任务管理器一致
    ffmpeg安装及使用
    Spring Boot 日志文件
    Spring MVC框架学习(五) ---- 传递参数
    高级数据结构:最小生成树及普里姆算法
    centos7的忘记root管理员账号的登录密码
    iOS全埋点解决方案-应用退出和启动
    C++面向对象OOP-构造函数
  • 原文地址:https://blog.csdn.net/Lbsssss/article/details/126614427