前言

  • Android开发中,Handler媒介机制十分常用,今天我们来详细聊一聊Handler通讯机制是如何实现的。

目录

Omb4mt.png

使用场景

在多线程的应用场景中,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现工作线程对UI线程的更新,最终实现异步消息的处理。

概念描述

Handler、Message、MessageQueue、Looper相关概念如下图。

概念 定义 作用
主线程
( UI线程、Main Thread )
系统首次启动,会创建主线程 处理UI相关操作
( 如:更新UI )
子线程
( 工作线程 )
人为开启的线程 执行耗时任务
( 如 网络请求、数据加载等 )
消息
( Message )
线程间通讯数据单元
(handler接收&处理消息对象)
存储业务操作信息
( Message )
消息队列
( Message Queue )
数据结构
( 以时间顺序排列 )
存储Handler发送的消息
( Message )
处理着
( Handler )
主线程与子线程通讯的媒介
线程消息的处理者
将消息( Message )添加到
消息队列( Message Queue )中
处理循环器( Looper )分派的消息
循环器
( Looper )
消息队列( Message Queue )
与处理者 ( Handler )
通讯媒介
消息循环 即:
消息获取:循环取出消息队列
( Message Queue )中的
消息( Message )
消息分发:将取出来的消息
( Message )发送给对应的
处理者( Handler )

机制说明

Handler消息传递机制:多个线程并发更新UI时,保证线程安全
示例图.png
注:图解Java线程安全

原理解析

相关概念

  • 异步通信( 主线程中创建 )

    处理者( Handler )对象

    注:Handler会自定绑定主线程中的Looper&MessageQueue

    处理器( Looper )对象

    注:Looper & MessageQueue都是在主线程中

    消息队列( Message Queue )对象

    注: 创建MessageQueue后,Looper会自动进入循环状态,有消息则循环取,没有,则阻塞状态,发现消息后会被唤醒继续循环读取。

  • 消息入队列

    工作线程中通过Handler的sendMessage()方法发送消息( Message )到消息队列( MessageQueue )中,这是消息完成入队列操作。

    注:此消息内容就是工作线程对UI主线程的操作

  • 消息循环

    第一步:消息出队列:Looper循环取出消息队列( MessageQueue )中的消息( Message )交给第二步消息分发。
    第二步:消息分发:Looper将取出来的消息( Message )发送给创建消息的处理者( Handler )

    注:循环器( Looper )循环取消息时,若发现消息队列( MessageQueue )中为空,则会线程阻塞,待又消息时再次被唤醒继续循环读取。

  • 消息处理

    处理者( Handler ) 在接收处理器( Looper )发送过来的消息( Message )会进行UI操作。

示意图.png

注:Android中为什么主线程不会因为Looper.loop()里的死循环卡死?

总结

Android开发中,UI操作在主线程中进行,但是主线程又不能进行耗时操作,否则会阻塞线程,产生我们常见的ANR异常,所以常常把耗时操作放到其它子线程进行。如果在子线程中需要更新UI,一般是通过 Handler发送消息( message ),主线程接收消息并且进行相应的处理。以上就是Handler通讯消息传递机制的详解。

如果觉得此文章对你有所帮助,👍🏻请点个赞👍🏻