Handler消息机制基础讲解
[TOC]
文章参考:https://blog.csdn.net/weixin_43766753/article/details/108968666
概述
Handler消息机制学习之Handler对象
[TOC]
概述Handler消息机制我们都不陌生,在日常开发中不可避免地要涉及这方面的内容。从开发的角度来说,Handler是Android消息机制的上层接口,这使得在开发过程中只需要和Handler交互即可。Handler的使用过程很简单,通过它可以轻松地将一个任务切换到Handler所在的线程中去执行。
Handler是什么很多时候,我们都认为Handler的作用是更新UI。其实这个认识是错误的,至少是非常局限的一个认识,Handler的中文意思是处理器、处理者的意思。所以其实跟更新UI本质上没有什么关系。其实Handler更应该理解为:绑定特定线程的消息处理器。
什么叫绑定特定线程? 我们可以看一下Handler的构造函数。
构造函数1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 // 代码位于:/f ...
Handler消息机制学习之Looper对象
简介很多人面试肯定都被问到过,请问Android中的Looper , Handler , Message有什么关系?本篇博客目的首先为大家从源码角度介绍3者关系,然后给出一个容易记忆的结论。
Handler 、 Looper 、Message 这三者都与Android异步消息处理线程相关的概念。那么什么叫异步消息处理线程呢?
异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环。若消息队列为空,线程则会阻塞等待。说了这一堆,那么和Handler、Looper、Message有啥关系?其实Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息,而消息的创建者就是一个或多个Handler 。
所以,下面我们依次讲解一下这几个东西。看他们到底是个什么鬼?
Looper对象源码首先,我们来看Looper对象,对于Looper主要是prepare()和loop()两个方法。
首先,我们看一下Looper的prepare方法
1234 ...
Handler消息机制学习之Message对象
[TOC]
概述
Handler消息机制学习之MessageQueue对象
[TOC]
MessageQueue#next()方法123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143@UnsupportedAppUsage Message next() { // 如果消息循环已经退出了。则直接在这里return。因为调用disposed()方法后mPtr=0 // 其实就是底层的NativeMessageQueue的应用已经被释放 ...
Handler消息机制学习之消息的同步屏障
文章参考:https://juejin.cn/post/6940607471153053704
概述我们回过去看看Handler的构造函数函数。你会发现一个Handler的构造函数。这个构造函数我们一般不常用。而且这个构造函数加上了@UnsupportedAppUsage注解。说明这个构造函数是不支持我们来用的。
1234567891011121314151617181920212223242526272829303132/** * 判断这个Handler发送的消息是不是异步Handler消息 */final boolean mAsynchronous;/** * * 默认情况下,Handler处理消息是同步的,除非使用此构造函数来创建异步处理的构造函数。 * 异步消息不受{@link MessageQueueenqueueSyncBarrier(long)}引入的同步障碍的约束 * @param async如果为true,则Handlerh会针对发送给它的每个Message或发布给它的 * Runnable程序调用{ ...
Handler消息机制学习之IdleHandler
[TOC]
概述Handler中的IdleHandler到底是个什么东西??这个是面试经常问的。它有什么能力?它有什么用处?能想到一些合适的场景吗?
IdleHandler 可以用来提升性能,主要用在我们希望能够在当前线程 消息队列空闲时 做些事情(例如UI线程在显示完成后,如果线程空闲我们就可以提前准备其他内容)的情况下,不过最好不要做耗时操作。
首先看下源码的注释:
123456789101112131415/** * Callback interface for discovering when a thread is going to block * waiting for more messages. * 可以理解为消息暂时处理完的适合回调的 */public static interface IdleHandler { /** * Called when the message queue has run out of messages and will now * wait for more. Return true to keep yo ...
Handler消息机制之Native层原理实现
[TOC]
文章参考:http://gityuan.com/2015/12/27/handler-message-native/
概述前面几章我们讲解了Java层的消息处理机制,其中MessageQueue类里面涉及到多个native方法,除了MessageQueue的native方法,native层本身也有一套完整的消息机制,用于处理native的消息,如下图Native层的消息机制。
在整个消息机制中,而MessageQueue是连接Java层和Native层的纽带,换言之,Java层可以向MessageQueue消息队列中添加消息,Native层也可以向MessageQueue消息队列中添加消息,接下来来看看MessageQueue。
我们再来简单回顾一下MessageQueue的对象。
MessageQueue在MessageQueue中的native方法如下:
1234567// 代码位于:/frameworks/base/core/java/android/os/MessageQueue.javaprivate native static long nativeInit() ...
Handler消息机制之Native层原理实现
[TOC]
文章参考:http://gityuan.com/2015/12/27/handler-message-native/
概述前面几章我们讲解了Java层的消息处理机制,其中MessageQueue类里面涉及到多个native方法,除了MessageQueue的native方法,native层本身也有一套完整的消息机制,用于处理native的消息,如下图Native层的消息机制。
在整个消息机制中,而MessageQueue是连接Java层和Native层的纽带,换言之,Java层可以向MessageQueue消息队列中添加消息,Native层也可以向MessageQueue消息队列中添加消息,接下来来看看MessageQueue。
Native层业务类图
我们再来简单回顾一下MessageQueue的对象。
MessageQueue在MessageQueue中的native方法如下:
1234567// 代码位于:/frameworks/base/core/java/android/os/MessageQueue.javaprivate native static long ...
面试题-为什么主线程不会因为Looper.loop()死循环卡死
文章参考:https://www.zhihu.com/question/34652589
如果看过源码的人都知道,在处理消息的时候使用了Looper.loop()方法,并且在该方法中进入了一个死循环,同时Looper.loop()方法是在主线程中调用的,那么为什么没有造成阻塞呢?
首先我们需要从Android程序启动的入口开始来看:
1234567891011121314151617181920212223242526272829303132333435 public static void main(String[] args) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");// ...... Process.setArgV0("<pre-initialized>"); // 初始化主线程的looper对象 Looper.prepareMainLooper(); / ...