Android基础知识(四)Handler机制

前言

在传统的Android开发中,经常会使用Handler进行线程调度,消息分发等任务。为什么说传统呢,因为如今通通可以用RxJava来实现。但这并不影响我们需要了解Handler机制,它存在于Android最基础的一个类ActivityThread中,Android就是利用Handler机制来控制四大组件的生命周期。

Handler源码解析

Handler的主要作用为事件的调度(分发),我们从构建->处理->回调的顺序来讲解Handler。

Android基础知识(四)Handler机制_第1张图片
图片.png

Handler的主要构造方法就两个,没有本质区别,重点就是Handler要依赖于Loop。

图片.png

其中的Looper.myLooper() 方法获得的是当前线程中的Looper。所以若要在子线程中创建Handler必须在创建前后加上Looper,否则mLooper为空会报上图异常。

Android基础知识(四)Handler机制_第2张图片
图片.png

在使用Handler时,通常使用的是post方法或者使用postDelayed方法进行延时运行。无论是调用上面两种或者其他post方法,实质为将Runnable包装成Message并放入MessageQueue消息队列中。在构造方法中我们就知道,消息队列来自于Looper。

Android基础知识(四)Handler机制_第3张图片
图片.png

另外还有常用的sendEmptyMessage或者sendMessage进行消息的传送。与post相同,最终也是调用sendMessageAtTime方法。在Handler中还有看到一系列的obtainMessage方法。较new Message()来说,使用 obtainMessage方法更优。

Android基础知识(四)Handler机制_第4张图片
图片.png

原因是obtain中获取的message会进行复用,省去了对象创建的时间。
sendEmptyMessage方法中也是使用的obtain方式获取Message。

在Message在消息队列中被调度时(排队排到了)回到Handler中进行分发,确定回调的路径。

Android基础知识(四)Handler机制_第5张图片
图片.png

首先msg.callback实际为Runnable,如果存在就跑Runnable的run方法。接着Handler的Callback进行拦截处理,确定是否继续传递。最后回调Handle的handleMessage。

看到这里发现了一个一直以来理解上的问题,Handler中post一个Runnable是否在子线程中进行。答案明显不是的,在Handler中直接调用了Runnable的run方法。

Android基础知识(四)Handler机制_第6张图片
图片.png

通过代码验证后,得到运行在主线程。正确的使用handler进行线程切换应该为在子线程中调用handler.post 进行消息发送。

Android基础知识(四)Handler机制_第7张图片
图片.png

Looper源码解析

Looper需要与Handler配合使用。上文已经提过线程中默认是没有Looper,如果需要使用需要对Looper进行初始化。

Android基础知识(四)Handler机制_第8张图片
图片.png

代码中指出一个线程对应一个Looper。quitAllowed为能否退出消息队列的标记位。为了方便阅读,在此上此图。

Android基础知识(四)Handler机制_第9张图片
图片.png

在Looper初始化之后,对需要进行循环的内容进行初始化,我们只是简单的定义Handler。所有工作准备就绪,调用loop方法。loop是循环的意思,在源码中可以看出这是一个死循环。

Android基础知识(四)Handler机制_第10张图片
图片.png

从简化的loop中可以观察到

  1. loop是一个处理MessageQueue的死循环
  2. 此处的msg.target就是Handler,回调到Handler的dispatchMessage方法中。
  3. 最后从将Messgae解锁释放
Android基础知识(四)Handler机制_第11张图片
图片.png

ActivityThread

有了Handler机制的铺垫,相信ActivityThread中的方法还是比较容易分析的。在此只简要分析与消息分发相关内容。

Android基础知识(四)Handler机制_第12张图片
图片.png
Android基础知识(四)Handler机制_第13张图片
图片.png

一路找上去发现sMainThreadHandler就是在ActivityThread中定义的H类,而H继承于Handler。H类中真正对生命周期等进行处理。

此处发现,在Activity中对Looper初始化调用的不是我们使用的prepare方法,而是prepareMainLooper(),在Loop中也注释到该方法使用与application的main looper,不要自行调用。

提问

若在子线程中用Looper.getMainLooper初始化Handler,回调方法会在主线程还是子线程?

Android基础知识(四)Handler机制_第14张图片
图片.png

总结

原意是为了学习ActivityThread,但在分析完Handler机制后发现此类中已经明了了大半,当然还有Context绑定时机,Application启动等相当多的内容。Handler和Looper实际是比较容易读的源码,当然是在理解原理不要求编写的情况下。感慨大牛码力的同时继续努力编码。

你可能感兴趣的:(Android基础知识(四)Handler机制)