handler.post(Runnable) runnable是如何执行的?(字节跳动、小米)

前言

看一遍不如写一边,每个人都有自己的理解

主要分析runnable 是如何被封装成为一个message,以 它如何被添加到messageQueue里面的过程,最后再分析这个message如何运行的过程。

Runnable分发

首先我们看一下handler.post(Runnable)的相关源码

less 复制代码
public final boolean post(@NonNull Runnable r) {
       return  sendMessageDelayed(getPostMessage(r), 0);
}
​
private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
}
​
public final boolean sendMessage(@NonNull Message msg) {
        return sendMessageDelayed(msg, 0);
}
​

从上面代码我们可以看出,post(Runnable)方法使用到的sendMessageDelayed函数,其实也就是调用了sendMessage(Message msg)。只是它使用到了我们的getPostMessage函数,将我们的Runnable转化为了我们的Message,由此可知handler.post(Runnable) 分发阶段实质上是和普通的Message是一样的。

Runnable执行

接着Message会通过queue.enqueueMessage(msg, uptimeMillis)方法被添加到MessageQueen中,由Looper#loop完成消息的分发执行。最终Looper#loop中会将消息发送至Handler#dispatchMessage处理:

scss 复制代码
/**
 * Handle system messages here.
 */
public void dispatchMessage(@NonNull Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}
    
private static void handleCallback(Message message) {
    message.callback.run();
}

Handler#dispatchMessage中Handler.dispatchMessage中如果判断需要分发执行的Message对象中callback(即post的Runnable)不为空,最终调用的是callback.run()方法,完成runnable的执行动作。

今日分享到此结束,对你有帮助的话,点个赞再走呗,每日一个面试小技巧
关注公众号:Android老皮

解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已形成PDF版

内容如下

1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路

相关推荐
windliang1 小时前
Claude Code 源码分析(五):一次 Tool 调用怎样通过权限检查
前端·人工智能·面试
鹿角片ljp5 小时前
Redis 深度复习:从入门到面试通关
数据库·redis·面试
KaifuZeng6 小时前
电源面试问题汇总三
单片机·嵌入式硬件·面试·电路
swipe7 小时前
16|(前端转全栈)前端人排查后端问题:curl、traceId、日志、MySQL、Redis 怎么用?
前端·后端·面试
用户0510122572967 小时前
DAY 5-智能指针与 C++ 内存管理
c++·面试
FogLetter8 小时前
进程VS线程:你的电脑到底是怎么同时干那么多活的?
前端·面试
FogLetter8 小时前
我真的写了个“诈尸式”缓存组件:手撕React KeepAlive
前端·react.js·面试
Lzh编程小栈9 小时前
【STM32底层精讲】RCC时钟系统超全详解(时钟树+源码+避坑指南)
c语言·stm32·单片机·嵌入式硬件·面试
艾莉丝努力练剑11 小时前
【MYSQL】MYSQL学习的一大重点:事务(上)- 原子性与持久性
android·数据库·学习·mysql·面试
西安小哥1 天前
AI时代全栈面试通关指南:从背八股到聊架构
面试·ai编程