• Handler 源码分析


    Handler用法:

    无参 Handler 构造函数实例化一个 Handler 类型的全局变量,并重写其 handleMessage 方法,在某一方法内调用 Handler 的 sendEmptyMessage 或者sendMessage 发送消息,在某一时刻 handleMessage 回调方法会被调用 。

    Handler 内部定义的两个 final 对象

    final MessageQueue mQueue ;
    
    final Looper mLooper ;

    MessageQueue 即为其内部的消息队列, mQueue 是通过 Looper 的静态变量 mQueue 直接赋值的。而 mLooper是通过 Looper 的静态方法 myLooper() 赋值。

    Looper.myLooper() 实质上调用了 sThreadLocal.get() 来获取与当前线程相关联的 Looper ,源码里面有这样一句话

     // sThreadLocal.get() will return null unless you've called prepare().

    ,在调用该方法之前必须先调用 prepare() 方法,否则该方法返回 null 。但事实上我们并没有调用这个方法,却能成功,原因是为什么呢?

    Looper 内部提供了一个静态方法 prepareMainLooper ,这个方法是在应用程序创建的时候直接由 android 系统调用的。

    /** Initialize the current thread as a looper, marking it as an application's main
    
         *  looper. The main looper for your application is created by the Androidenvironment,
    
         *  so you should never need to call this function yourself.
    
    */

    该方法调用了 prepare () 方法和 setMainLooper (myLooper ()) 并将 myLooper () 返回的值设置为主线程的 looper 。

    接下来看 sendEmptyMessage 和其他几个发送消息的方法,它们最终都会调用到 sendMessageAtTime 这样一个方法,而这个方法会调用 MessageQueue 提供的 enqueueMessage 方法,该方法将发送的消息放入消息队列里面,最后调用

    nativeWake(mPtr) 方法,这是一个 C++ 实现的方法,具体的实现内容没有深究,但应该间接调用到 Looper loop() 方法。

    接下来看一下 loop() 方法,这个方法从消息队列中取出消息,然后调用里面存放的 target 的 dispatchMessage 方法:

    msg.target.dispatchMessage(msg);

    msg.target 存放的是在构造消息的类的 handler 对象,事实上这里回调了 handler 的 dispatchMessage 方法,该方法会调用 handleMessage 方法。

  • 相关阅读:
    注解方式整合mybatis & SpringBoot整合分页助手 & SpringBoot整合JSP
    xml方式整合mybatis
    @SpringBootApplication&多环境配置&引入外部配置信息
    用例图&类图
    OOP特性介绍&域模型&静态建模和动态建模
    Git标签
    Git分支
    zabbix监控es集群健康状态(python2.7)
    Django使用问题记录
    failed to update local proxy configuration copy: unexpected field "hosts.available"解决
  • 原文地址:https://www.cnblogs.com/xinmengwuheng/p/5792488.html
Copyright © 2020-2023  润新知