深入了解IdleHandler,用来做优化或者轻量级任务都是极好的

简介: IdleHandler 是 Handler 提供的一种充分利用CPU的机制, 主要是在 MessageQueue 出现空闲的时候被执行
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

在这里插入图片描述

一、导读

我们继续总结学习Android 基础知识,温故知新。

二、概览

IdleHandler 是 Handler 提供的一种充分利用CPU的机制, 主要是在 MessageQueue 出现空闲的时候被执行,
运行在Looper 所在的线程中,队列出现空闲存在两种场景:

  • 循环拿到的Message为空
  • 这个Message是一个延时的消息;

另外由于IdleHandler 的处理时机不可控,如果 MessageQueue 一直有待处理的消息,那么 IdleHander 的执行时机会很靠后,
所以需要根据具体业务来决定是否使用这样的延迟加载。

三、使用

使用起来非常简单,几行代码即可

    protected void initIdleHandler() {
        MessageQueue.IdleHandler() idleHandler = new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                // TODO: 2023/7/21  
                return true; 当消息队列内没有需要立即执行的消息时,都会触发该方法
                return false;即只会执行一次;
            }
        };
        Looper.myQueue().addIdleHandler(idleHandler);
    }

    手动移除
    Looper.myQueue().removeIdleHandler(idleHandler);
        

3.1 使用场景

主要用于在消息队列空闲的时候处理一些轻量级的工作,
在不影响其他任务,在消息队列空闲状态下执行,如加载图片,延迟初始化,Android Framework层的GC 等

四、原理

IdleHandler看起来好像是个Handler,但他其实只是一个有单方法的接口,是MessageQueue静态内部接口。

    返回值为 false,即只会执行一次;
    返回值为 true,即每次当消息队列内没有需要立即执行的消息时,都会触发该方法。

    public static interface IdleHandler {
        /**
         * Called when the message queue has run out of messages and will now
         * wait for more.  
         * Return true to keep your idle handler active, 
         * false
         * to have it removed.  
         * 
         */
        boolean queueIdle();
    }

在MessageQueue中有一个List存储了IdleHandler对象,当MessageQueue没有需要被执行的MessageQueue时就会遍历回调所有的IdleHandler。
其处理逻辑在 MessageQueue.java 的next方法中,如下:

Message next() {
    ......
    死循环
    for (;;) {
        if (nextPollTimeoutMillis != 0) {
            Binder.flushPendingCommands();
        }
        //1.阻塞函数
        nativePollOnce(ptr, nextPollTimeoutMillis);
        //2.从链表里面取出消息
        ......
            //3.开始处理IdelHandler
            if (pendingIdleHandlerCount < 0
                    && (mMessages == null || now < mMessages.when)) {
                pendingIdleHandlerCount = mIdleHandlers.size();
            }
            if (pendingIdleHandlerCount <= 0) {
                // No idle handlers to run.  Loop and wait some more.
                mBlocked = true;
                continue;
            }

            if (mPendingIdleHandlers == null) {
                mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
            }
            mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
        }


        // 执行IdleHandler队列中的空闲任务
        for (int i = 0; i < pendingIdleHandlerCount; i++) {
            final IdleHandler idler = mPendingIdleHandlers[i];
            try {
                keep = idler.queueIdle();
            } catch (Throwable t) {
            }
            
            //4.如果keep为false,则就从列表当中去除
            if (!keep) {
                synchronized (this) {
                    mIdleHandlers.remove(idler);
                }
            }
        }
        

        ...
    }
}

如果循环拿到的Message为空,或者这个Message是一个延时的消息,也即当前没有可执行Message,则认为是一个空闲,
这时就开始遍历mIdleHandlers数组, 使用临时数组来保存当前要执行的消息,循环中从数组中取出 IdleHandler,并调用其 queueIdle() 方法。

其流程也并不复杂,我借用一张网络图
在这里插入图片描述

public void addIdleHandler(@NonNull IdleHandler handler) {
    if (handler == null) {
        throw new NullPointerException("Can't add a null IdleHandler");
    }
    synchronized (this) {
        mIdleHandlers.add(handler);       //mIdleHandlers是一个ArrayList
    }
}

相关文章
ly~
|
1月前
|
存储 算法 编译器
游戏开发中,C 语言的性能优势体现在哪些方面?
在游戏开发中,C 语言凭借其对硬件的直接访问和内存操作的精准控制,能够显著提升性能。它允许开发者手动管理内存,优化数据存储和读取,充分利用显卡等硬件资源,实现流畅的图形渲染和音效处理。作为一种接近底层的语言,C 语言具有高效的执行速度,适用于物理引擎和碰撞检测等高性能需求模块,并且提供了丰富的运算符和数据类型,便于实现高效的算法。此外,C 语言代码具有良好的可移植性和跨平台性,支持多种操作系统和硬件平台,减少了多平台发布的开发成本。编译器提供的优化选项和手动代码优化的灵活性进一步提升了游戏的整体性能。
ly~
89 5
|
6月前
|
数据库 Android开发 开发者
构建高性能微服务架构:从理论到实践构建高效Android应用:探究Kotlin协程的优势
【2月更文挑战第16天】 在当今快速迭代和竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性和独立部署能力而受到企业的青睐。本文将深入探讨如何构建一个高性能的微服务系统,涵盖从理论基础到具体实现的各个方面。我们将重点讨论服务拆分策略、通信机制、数据一致性以及性能优化等关键主题,为读者提供一个清晰、实用的指南,以便在复杂多变的业务环境中构建和维护健壮的微服务体系结构。 【2月更文挑战第16天】 在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着技术的不断进步,Kotlin作为一种现代编程语言,在Android开发中被广泛采用,尤其是其协程特性为异步编程带来了革命性的改进。本文旨在深入
|
存储 消息中间件 缓存
相比游戏客户端,游戏服务端开发无关紧要吗
感觉游戏服务端,除了更新,保存数据啊、生成随机物品啊、都没什么了,好像游戏开发场景中,服务端已经无关紧要了。看着客户端忙成狗,正在摸鱼的你是否也有过这样的疑问?
618 0
相比游戏客户端,游戏服务端开发无关紧要吗
|
1月前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
49 2
|
2月前
|
Kubernetes Java 编译器
解锁极致性能:Quarkus如何让JVM应用调优变得前所未有的简单与高效!
Quarkus是一款专为GraalVM和OpenJDK设计的Kubernetes Native Java框架,采用AOT编译技术将Java应用转化为本地代码,大幅提升启动速度与运行效率。它简化了性能调优流程,如自动优化垃圾回收、类加载、内存管理及线程管理等,使开发者无需深入理解JVM细节即可轻松提升应用性能。与传统JVM应用相比,Quarkus显著降低了性能调优的复杂度。
99 2
|
3月前
|
缓存 监控 Android开发
构建高效的Android应用:从内存优化到用户体验
【7月更文挑战第57天】 在竞争激烈的移动市场中,一个高效、流畅且具有优秀用户体验的Android应用是成功的关键。本文将深入探讨如何通过内存管理和界面优化来提升应用性能,包括实用的编程技巧和策略,以及如何利用Android系统提供的工具进行调试和性能监控。读者将学习到如何识别和解决常见的性能瓶颈,以及如何设计出既美观又实用的用户界面。
|
5月前
|
缓存 监控 算法
构建高性能Java应用的秘诀
构建高性能Java应用的秘诀
|
6月前
|
存储 缓存 算法
深入理解操作系统内存管理:分页系统的优势与挑战构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第27天】 在现代计算机系统中,内存管理是操作系统的核心功能之一。分页系统作为一种内存管理技术,通过将物理内存划分为固定大小的单元——页面,为每个运行的程序提供独立的虚拟地址空间。这种机制不仅提高了内存的使用效率,还为多任务环境提供了必要的隔离性。然而,分页系统的实现也带来了一系列的挑战,包括页面置换算法的选择、内存抖动问题以及TLB(Translation Lookaside Buffer)的管理等。本文旨在探讨分页系统的原理、优势及其面临的挑战,并通过分析现有解决方案,提出可能的改进措施。
|
6月前
|
缓存 移动开发 Android开发
构建高效Android应用:内存优化实战指南
【4月更文挑战第25天】 在移动开发领域,应用程序的性能至关重要。特别是对于Android设备,由于硬件配置的多样性,合理的内存管理与优化是提升应用流畅度、减少卡顿和崩溃的关键。本文将深入探讨Android应用的内存优化技巧,通过分析内存泄漏的原因、诊断工具的运用以及实际代码层面的改进措施,帮助开发者构建更加高效的Android应用。
|
6月前
|
存储 缓存 数据库
构建高效Android应用:内存优化策略深度剖析
【4月更文挑战第29天】 在移动开发领域,性能一直是衡量应用质量的关键指标之一。特别是对于Android平台,由于设备硬件配置的多样性,内存管理成为开发者面临的一大挑战。本文将深入探讨Android应用内存优化的有效策略,旨在帮助开发者提升应用性能,减少内存消耗,避免常见的内存泄漏问题。通过对Android内存管理机制的分析与实际案例的结合,我们将提供一系列实用的优化技巧,助力应用在竞争激烈的市场中脱颖而出。
下一篇
无影云桌面