当前位置: 首页 > news >正文

Android之Handler(上)

Handler机制的相关类

Hanlder:发送和接收消息 Looper:用于轮询消息队列,一个线程只能有一个Looper Message: 消息实体
MessageQueue: 消息队列用于存储消息和管理消息

创建Looper

在这里插入图片描述
在ActivityThread中的main方法中为我们prepare了在这里插入图片描述
在这里插入图片描述
prepare有两个重载的方法,主要看 prepare(boolean quitAllowed) quitAllowed的作用是在创建MessageQueue时标识消息队列是否可以销毁, 主线程不可被销毁,下面有介绍
在这里插入图片描述

创建MessageQueue以及Looper与当前线程的绑定
在这里插入图片描述
MessageQueue的构造方法
在这里插入图片描述

Looper.loop()

同时是在main方法中 Looper.prepareMainLooper() 后Looper.loop(); 开始轮询
在这里插入图片描述

创建Handler

最常见的创建handler
在这里插入图片描述
在内部调用 this(null, false);
在这里插入图片描述
Looper.myLooper();
在这里插入图片描述
sThreadLocal.get() will return null unless you’ve called prepare(). 这句话告诉我们get可能返回null 除非先调用
prepare()方法创建Looper。在前面已经介绍了

创建Message

可以直接new Message 但是有更好的方式 Message.obtain。因为可以检查是否有可以复用的Message,用过复用避免过多的创建、销毁Message对象达到优化内存和性能的目地
在这里插入图片描述
创建Message的时候可以通过 Message.obtain(Handler h) 这个构造方法绑定。当然可以在 在Handler 中的enqueueMessage()也绑定了,所有发送Message的方法都会调用此方法入队,所以在创建Message的时候是可以不绑定的
在这里插入图片描述

Handler发送消息

Handler发送消息的重载方法很多,但是主要只有2种。 sendMessage(Message) sendMessage方法通过一系列重载方法的调用,sendMessage调用sendMessageDelayed,继续调用sendMessageAtTime,继续调用enqueueMessage,继续调用messageQueue的enqueueMessage方法,将消息保存在了消息队列中,而最终由Looper取出,交给Handler的dispatchMessage进行处理
我们可以看到在dispatchMessage方法中,message中callback是一个Runnable对象,如果callback不为空,则直接 调用callback的run方法,否则判断mCallback是否为空,mCallback在Handler构造方法中初始化,在主线程通直接 通过无参的构造方法new出来的为null,所以会直接执行后面的handleMessage()方法。
在这里插入图片描述

Handler处理消息

在handleMessage(Message)方法中,我们可以拿到message对象,根据不同的需求进行处理,整个Handler机制的流程就结束了。

小结

handler.sendMessage 发送消息到消息队列MessageQueue,然后looper调用自己的loop()函数带动MessageQueue从而轮询messageQueue里面的每个Message,当Message达到了可以执行的时间的时候开始执 行,执行后就会调用message绑定的Handler来处理消息。大致的过程如下图所示
在这里插入图片描述
handler机制就是一个传送带的运转机制。
1)MessageQueue就像履带。
2)Thread就像背后的动力,就是我们通信都是基于线程而来的。
3)传送带的滚动需要一个开关给电机通电,那么就相当于我们的loop函数,而这个loop里面的for循环就会带着不断 的滚动,去轮询messageQueue
4)Message就是 我们的货物了。

相关文章:

  • 网络协议:网络安全
  • php防止SQL注入的网上二手交易平台的设计与实现毕业设计-附源码241552
  • 美团笔试题目(Java后端5题2小时)
  • HTML期末大学生网页设计作业——奇恩动漫HTML (1页面) HTML CSS JS网页设计期末课程大作业
  • 浅谈如何学习网络编程
  • 【MYSQL】表的增删改查
  • 中国地板工具租赁服务行业竞争态势与经营效益预测报告2022-2028年
  • 查看docker 容器的端口
  • xubuntu16.04系统中隐藏网络连接的弹窗提示
  • 基于HTML的环境网站设计 HTML+CSS环保网站项目实现 带设计说明psd
  • 第25集丨人生中最高的精神价值
  • php+mysql计算机公共课在线学习网站
  • Git工具快速入门_一小时速成
  • 声明式HTTP客户端-Feign 使用入门详解
  • 未来:spring响应式编程 Hands-On Reactive Programming in Spring 5(三),spring事件监听
  • php的引用
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • es的写入过程
  • java 多线程基础, 我觉得还是有必要看看的
  • Javascript编码规范
  • Koa2 之文件上传下载
  • Lucene解析 - 基本概念
  • magento2项目上线注意事项
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • 创建一个Struts2项目maven 方式
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 交换综合实验一
  • ​io --- 处理流的核心工具​
  • #etcd#安装时出错
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (C++20) consteval立即函数
  • (C语言)二分查找 超详细
  • (poj1.2.1)1970(筛选法模拟)
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (四)linux文件内容查看
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)程序员技术练级攻略
  • (转)视频码率,帧率和分辨率的联系与区别
  • (转)详解PHP处理密码的几种方式
  • .bat批处理(一):@echo off
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • /dev下添加设备节点的方法步骤(通过device_create)
  • ??javascript里的变量问题
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @selector(..)警告提示
  • [145] 二叉树的后序遍历 js
  • [DM复习]Apriori算法-国会投票记录关联规则挖掘(上)
  • [Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具
  • [EULAR文摘] 利用蛋白组学技术开发一项蛋白评分用于预测TNFi疗效
  • [IE编程] IE8 新增的C++开发接口