Android Handler机制了解多少

Android Handler机制了解多少

Handler的作用

一句话概括,就是将message或者runnable发送到当前线程绑定的MessageQueue当中,通过Looper对象不断的从MessageQueue中取出消息,放到指定的线程中去处理。

主要用途
  1. 安排message和runnable在将来的某个时刻执行
    tip:事实上通过handler发送延迟消息最终都是通过sendMessageDelayed调用到sendMessageAtTime来实现。
    Handler.java中有一个post方法

  2. 将要在不同于自己的线程上执行的操作排入队列
    在这里插入图片描述

成员
message handler接收和处理的消息对象
MessageQueue 消息队列,单链表结构,先进先出,每个线程只会绑定一个消息队列
Looper 消息队列的管理者,不断的从消息队列中取出消息,并将消息分发到对应的Handler处理,每个线程只有一个Looper

每个线程可以有多个handler

既然说到Handler机制,那么我们就需要查看一下源码,它内部消息处理的是一个怎么样的流程。
根据上面提到的handler的作用,能够知道消息的排入队列是通过调用MessageQueue对象的enqueueMessage这个方法实现的。我们就来看看这个enqueueMessage到底是怎样实现的。

MeesageQueue.java
在这里插入图片描述
方法内先是判断消息的目标handler是否为空,消息是否已经被使用。然后进入到同步块中判断消息队列是否正在退出。紧接着进入到556行的条件判断语句if当中,判断有消息是否已经进入,延时是否为0或者小于之前消息的延时,当有条件成立,则将新msg传给mMessages,并把next指向它,这是msg会在消息队列的最前面,等待loop的轮循。
如果不符合,就进入到else代码中,这里可以看到在567行有一个for的死循环,做了一个when < p.when 的判断,去遍历所有消息有比新消息延时长的消息,再将新的消息通过577,578行的逻辑排到前面去执行。

已经知道了消息是如何排入消息队列中的,那么消息又是如何从消息队列中取出来的呢?通过哪个对象进行操作的呢?接下来就需要分析MessageQueue另一个重要的方法next

MessageQueue.java
在这里插入图片描述

nextPollTimeoutMillis = 0 表示nativePollOnece立即返回
nextPollTimeoutMillis > 0 表示nativePollOnece延迟nextPollTimeoutMillis的时间
nextPollTimeoutMillis = -1 表示nativePollOnece进入阻塞状态

直接看320行,能知道在next方法当中也有一个死循环,这个循环虽然代码量很多,但实际操作是很简单。nativePollOnce是一个阻塞方法。在同步块中,首先判断是否msg头部消息是否是屏障消息,如果不是则跳到下一个条件判断 now<msg.when 中若还未到执行时间,就给nextPollTimeoutMillis一个阻塞的时间差,否则进入else中,最后将msg返回出去。倘若msg为空,则nextPollTimeoutMillis置于-1 表示已经没有需要处理的消息。这个时候就进入阻塞状态。

tip:同步块中的第一个if条件判断是判断msg.target是否为空,进而执行。而什么时候msg.target为空呢?就是当MessageQueue.postSyncBarrier 发送同步屏障来保障handler将所有的同步消息不会被执行。同时可以通过Message.setAsynchronous来设置发送的消息为异步消息。

我们知道每个线程都对应一个Looper对象,只是主线程在启动的过程中,其实已经创建了这个Looper。

Looper.java
在这里插入图片描述

通过Looper.loop()方法能知道,141行能看到是一个无限循环,执行queue.next()去调用上面提到的消息队列中的next方法取出消息。当队列当中没有消息时,loop方法也会阻塞。
当Looper对象从MessageQueue中取出消息,在164行能看到通过msg.target的目标handler去执行它的dispatchMessage方法将取出的消息分发到指定线程的handleMessage中执行。

tip:handler在发送消息message的时候,通过sendMessageAtTime调用到自身的enqueueMessage方法,就会给当前message的target赋值为当前handler,所以在最后取出消息的时候,只需要通过msg.target就可以获取指定的handler去处理消息。

Handler.java
在这里插入图片描述
至此,handler机制就已经写完了,handler机制在我们平时开发过程中经常会使用的到,但是其内部的原理我们又了解多少呢,通过查看源码,能够让我们更清楚的明白内部的处理的过程,加深记忆和更深的使用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值