zoukankan      html  css  js  c++  java
  • Android学习笔记——从源码看Handler的处理机制

    可能是出于性能的考虑,Android的UI操作是非线程安全的。

    也就是说,如果你在一个新开的线程中直接操作UI是会引发异常的。

    但是,Android又规定,不要去阻塞UI线程!否则,轻者引起程序卡顿,重者直接引发臭名昭著的“ANR”异常。

    为了解决这一种矛盾,Android引入了Handler来解决这个问题。

    Handler有两种常见的用法:

    第一种是“发送信息”,我们可以将我们要改变的参数通过Message发送给指定的Handler,然后在Handler中的handleMessage方法中进行处理。

    另一种是将一个runnable对象“post”给Handler对象去执行。

    实际上,这两种方法是没有太本质的区别的。

    接下来从源代码的角度来看Handler的整个运行机制。

    首先先来看看Message对象:

    message中有几个比较重要的成员变量

    what // 一个用来表示这个信息的类型

    arg1 // 参数1

    arg2 // 参数2

    object // 可以携带任何一个对象

    还有这一个:

    这个东东就是用来传递Runnable对象的。

    接下来看Handler的sendMessage方法:

     

    可以看到,它实际上是调用另一个发送的方法,我们跟进去:

     

    靠,原来这几个方法是一回事来的,继续看:

     

    终于不一样了~~~,这里多了一个MessageQueue对象,神马东西?从名字上看应该是“信息队列”的意思。也就是说,实际上,我们发送给Handler的信息并不是直接交给Handler去处理,而是Handler会把Message先放入一个MessageQueue中。MessageQueue就是一个数据结构,以队列的形式管理Message。那么,谁又把Message从Message从MessageQueue中拿出来呢?

    这就需要另一个对象Looper了。

    Looper的构造方法很有意思:

     

    那也就是说我们是无法直接创建Looper对象的,经验告诉我们,这种情况下,一般不是单例就是工厂。实际上是这个:

     

    这个方法保证了一个线程中只有一个Looper对象,否则会出现异常。

    实际上,Looper中有一个loop方法:

     

    上面是我把无关代码去掉后的loop方法,这个方法中looper对象一直去调用MessageQueue的next()方法,也就是不断地从消息队列中取出消息,然后重点来了:

     

    嗯,这一步就是把消息交给对应的Handler去处理。

    那么post一个Runnable对象又是怎么做到的呢?

     

    这方法看起来相当的亲切啊!猜应该也可以猜到了getPostMessage方法是怎么实现了吧:

     

    猜对没有?

    所以本质上都是通过发信息来实现的。

    看看dispatchMessage是怎么做的吧:

     

    接下来就好说了,如果callback不是null,那就是让它去run咯!如果是普通消息, 那就是靠我们自己写的handleMessage去处理了。

    至此,Handler的运行机制就是这些了。很喜欢张龙老师的一句话:源代码下,了无秘密。

    总结一下:

    Message:这个对象携带着我们想做的信息。

    MessageQueue:以队列的形式管理Message对象。

    Looper:每个线程只有一个Looper对象,它负责管理MessageQueue,会不断地从中取出Message对象,交给相应的Handler去处理。

    Handler:它把Message发送给Looper维护的MessageQueue,并负责处理Looper传递过来的Message对象。

    by yjiyjige 2013.06.19

  • 相关阅读:
    4.练习
    『Java面试题总结
    『Maven + Junit + Jacoco』单元测试覆盖率
    『Linux』命令
    『ElasticSearch』安装、健康值检查
    『类型转换』Object转Map、Map转Object
    『ElasticSearch』排序报错
    MD5加密解密网址总结
    汉字编码的理解
    ASCII码的理解
  • 原文地址:https://www.cnblogs.com/yjiyjige/p/3145052.html
Copyright © 2011-2022 走看看