MessageQueue 空闲的时候,会调用 IdleHandler 里面的方法,可用于启动优化,利用空闲时间加载配置,避免卡住 UI 的展示。

使用场景

1.Activity 的生命周期回调 #onStop 和 #onDestroy

2.启动优化(WebView的引擎提前加载)

booster ShadowWebView

基础使用

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {mainLooper.queue.addIdleHandler {//加载闲时任务false}
}

返回值 false 表示任务只会执行一次
返回值 true 表示任务会执行多次

原理

@UnsupportedAppUsage
private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();@UnsupportedAppUsage
Message next() {// Return here if the message loop has already quit and been disposed.// This can happen if the application tries to restart a looper after quit// which is not supported.final long ptr = mPtr;if (ptr == 0) {return null;}int pendingIdleHandlerCount = -1; // -1 only during first iterationint nextPollTimeoutMillis = 0;for (;;) {if (nextPollTimeoutMillis != 0) {Binder.flushPendingCommands();}nativePollOnce(ptr, nextPollTimeoutMillis);synchronized (this) {...// 如果第一次空闲,那么获取要运行的空闲程序的数量。// 空闲句柄仅在队列为空或第一条消息时运行// 在队列中(可能是一个同步屏障)是由于在将来被处理。if (pendingIdleHandlerCount < 0&& (mMessages == null || now < mMessages.when)) {pendingIdleHandlerCount = mIdleHandlers.size();}if (pendingIdleHandlerCount <= 0) {//没有空闲的处理程序可以运行。循环并等待更多时间。mBlocked = true;continue;}if (mPendingIdleHandlers == null) {mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];}mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);}// 运行空闲处理程序。// We only ever reach this code block during the first iteration.for (int i = 0; i < pendingIdleHandlerCount; i++) {final IdleHandler idler = mPendingIdleHandlers[i];mPendingIdleHandlers[i] = null; // release the reference to the handlerboolean keep = false;try {keep = idler.queueIdle();} catch (Throwable t) {Log.wtf(TAG, "IdleHandler threw exception", t);}if (!keep) {synchronized (this) {mIdleHandlers.remove(idler);}}}// Reset the idle handler count to 0 so we do not run them again.pendingIdleHandlerCount = 0;// While calling an idle handler, a new message could have been delivered// so go back and look again for a pending message without waiting.nextPollTimeoutMillis = 0;}
}

判断消息队列当前没有消息的时候会执行 mIdleHandlers 中的任务

消息队列是空的时候,插入一个屏障,会触发IdleHandler么?

答:不会,插入屏障,并不会唤醒线程

如果删除了屏障,消息队列空了,会触发IdleHandler么?

答:不会。处理完消息,发现目前没有消息要处理(也可以是触发时间没到),触发IdleHandler,处理完毕。会再次检查是否有消息要处理,因为IdleHandler触发时,有可能有新的消息插入消息队列。如果没有,进入休眠,再次被唤醒时,不会再次(重复)触发IdleHandler。简单的说就是消息队列处理完最后一个消息,休眠之前调用过IdleHandler,休眠之后被唤醒,还是没有要处理的消息,不会重复调用IdleHandler

如果消息队列只有一个屏障消息,插一个普通消息会触发IdleHandler么?

答:有可能。IdleHandler的触发条件是,消息队列为空,或者第一条消息的触发时间还没到。所以如果屏障的超时时间还没有到,也就是目前还没有消息要处理,会触发IdleHandler

如果消息队列只有一个屏障消息,插入一个异步消息会触发IdleHandler么?

答:有可能,关键看屏障的触发时间到了没有,如果没有到,就会触发IdleHandler,反之就不会。

注意事项

1.不要加载耗时任务

耗时任务会卡住其他任务的执行

2.不要添加太多任务

闲时加载的时候,会一次性处理完所有的闲时任务,时间太长会导致 ANR

资料

[1].IdleHandler你会用吗?记一次IdleHandler使用误区,导致ANR
[2].Handler之消息屏障你应该知道的

【Handler】IdleHandler相关推荐

  1. 【handler】Android定时每十分钟执行一次任务

    private Handler handler = new Handler(){public void handleMessage(Message msg) {super.handleMessage( ...

  2. 【python】常用内建模块

    [datetime] No1: 获取当前时间 No2: 时区转换 >>> from datetime import datetime, timedelta, timezone > ...

  3. 【Android】Handler 深度解析

    [Android]Handler 深度解析 前言 Handler 可以说贯穿了整个 Android 系统,在 Android 中扮演着相当重要的角色.我们开发中接触到的四大组件如 Activity.S ...

  4. Handler 与 IdleHandler 浅析

    版权声明:本文章原创于 RamboPan ,未经允许,请勿转载. 第一次 2019年03月05日 第一次 2019年03月05日 调整代码块 变量.类名.方法 标记统一 Handler 分析 虽然 H ...

  5. IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】...

    上一篇文章中,我们已经完成了服务端数据库的搭建,本篇主要处理多[传统HTTP][依赖CORE环境]客户端之间协同在线[SSO]以及不需要SSO的场景处理. 目标: 1)实现多类型客户端接入Identi ...

  6. 是男人就下100层【第四层】——Crazy贪吃蛇(2)

    在上一篇<是男人就下100层[第四层]--Crazy贪吃蛇(1)>中我们让贪吃蛇移动了起来,接下来我们来实现让贪吃蛇能够绕着手机屏幕边线移动而且能够改变方向 一.加入状态并改动代码 首先我 ...

  7. 【ES6】Proxy对象

    [ES6]Proxy对象 一.Proxy的基本用法 二.Proxy示例的方法 1)get() 2)set() 3)apply() 查看更多ES6教学文章: 参考文献 引言:ES6规范里面新增了Prox ...

  8. 【Netty】入门Netty官方例子解析(二)Time Server

    本文承接上文<[Netty]入门Netty官方例子解析(一)写个 Discard Server> ,接下来讲解官网文档中Netty入门官方例子第二个例子 Time Server 原文这个章 ...

  9. 《Linux内核设计与实现》读书笔记(七)- 中断处理【转】

    转自:http://www.cnblogs.com/wang_yb/archive/2013/04/19/3030345.html 中断处理一般不是纯软件来实现的,需要硬件的支持.通过对中断的学习有助 ...

最新文章

  1. mysql installer图解_MySQL Installer GUI - 图解
  2. 操作系统识别工具 xprobe2 p0f 简介
  3. 性能测试监控工具nmon安装及使用方法
  4. 如何在wine下为Source Insight配置字体
  5. java 树的数据结构_Java数据结构之树(二叉树)
  6. 8266获取网络时间
  7. 毕昇 JDK:为啥是ARM 上超好用的 JDK
  8. 牛客小白月赛13 解题报告
  9. CentOS安装中文man手册
  10. 火牛单片机rtc时钟配置_怎么用STM32F103RTC进行时钟的配置
  11. 从张量积(tensor product)到多重线性代数(multilinear algebra)
  12. MySQL-(1)查看用户权限、(2)用户授权、(3)删除用户权限 语法格式总结
  13. CodeUI Test:UIMap录制文件分析一
  14. Linux安装vim编辑器
  15. thinkphp 对接阿里云短信支付,其主要是新版composer对接阿里短信
  16. word中正文分栏重新换页问题
  17. 如何采集与分析RocketMQ客户端日志
  18. 麒麟linux硬盘安装,U盘安装中标麒麟Linux桌面版的方法
  19. 计算机维护专业自我鉴定,2016届计算机系统维护专业大学生毕业自我鉴定优秀范文...
  20. 股票交易日志4 12.16

热门文章

  1. 超简单二进制转十六进制口诀!!
  2. 学习互联网思维必读的十本书
  3. 如何在html中加入天气,几种HTML实现天气显示方案
  4. 国产单片机GD32系列开坑,带你零死角玩转GD32 第三章
  5. 搜索引擎:Frame of Reference 和 Roaring Bitmaps
  6. DataGridView查询数据
  7. 7月视灯视频号榜单:更替率59.4%,央视新闻居首;萌宠、美妆市场空白,母婴、旅行前景广阔;视频号直播多项更新强化社交和私域价值
  8. 页面跳转 和虚拟键盘的自动隐藏
  9. android studio 改字体,Android Studio设置、改变字体和主题的方法
  10. 2022年最新江西道路运输安全员模拟真题题库及答案