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

android Handler

一、Handler的作用
1、Handler的作用是在andorid中实现线程间的通信。我们常说的说的,子线程处理逻辑,主线程更新UI是上述情况的一个子集。

二、源码分析
1、Handler源码
源码地址:http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/java/android/os/Handler.java

2、具体分析
创建Handler并消费的过程
先看下Handler的构造函数的核心部分

mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
“Can’t create handler inside thread that has not called Looper.prepare()”);
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
Handler在默认构造函数里检查了当前线程是否是Looper线程,如果不是Looper线程就抛出异常。我们常在主线程直接

new Handler()
这样做之所以没问题,是因为ActivityThread默认创建了Looper对象。如果我们想在非主线程T里创建Handler对象需显示调用

Looper.prepare()
那另外一种构造Handler的方式是

public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
这种方法要显示的传进一个Looper对象。获取Looper对象的方法是

thread.getLooper();
前提是thread线程已经是looper线程,例如HandlerThread线程的对象就是looper线程。
通过以上2种方法,我们就创建可以创建一个Looper对象,此时可以直接构造一个Handler对象出来,并开启Loop循环

Looper.loop();//这是一个死循环for(;😉,此循环在线程T里执行
从构造函数核心部分可知,Handler通过mLooper对象持有了一个MessageQueue对象mQueue。loop循环就是在遍历这个mQueue,当有Message对象msg进入队列的时候,msg会被立刻通过

mQueue.next();//如果没有消息,会阻塞在这里
方法被取出,通过

msg.dispatchMessage();//在线程T里执行
回调给Handler处理,Handler再通过

handleMessage();//在线程T里执行
将消息下发给具体处理业务的逻辑。

生产的过程
还是先看一段源码

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
我们在所有其他线程A中,通过Handler的对象sendMessage或者post等方法生产的消息,最终都会通过这里被enqueue到该Handler持有Looper成员变量的MessageQueue成员变量中,enqueue的过程必须加锁,这里就不展开说了。

上面就是一个生产过程,实现了从线程A中将消息发送到线程T中。

三、总结
Handler必须搭配Looper使用,这是因为MessageQuene只有进出的接口,没有loop接口,需要Looper对象拿出消息并回调给Hander对象进行处理。

http://www.lryc.cn/news/231485.html

相关文章:

  • 【Ubuntu·系统·的Linux环境变量配置方法最全】
  • Django之模板层
  • 社区论坛小程序系统源码+自定义设置+活动奖励 自带流量主 带完整的搭建教程
  • 2023亚太杯数学建模C题思路解析
  • acme在同一台服务器上设置多个Ali_key实现自动ssl申请和续期
  • 乐观锁与悲观锁
  • 【算法】堆排序
  • 51单片机应用从零开始(三)
  • 如何在 Nginx Proxy Manager(NPM)上部署静态网站
  • http的几种方法
  • var、let、const关键字的特性,以及let、const暂时性死区的作用
  • IDEA 高分辨率卡顿优化
  • 【AIGC】一起学习prompt提示词(4/4)【经典】【15种提示词技巧】
  • Linux实战一天一个小指令--《文件管理/文件查找》
  • CocosCreator3.8神秘面纱 CocosCreator 项目结构说明及编辑器的简单使用
  • JJJ:python学习笔记
  • SpringSecurity6从入门到上天系列第七篇:讲明白SpringBoot的自动装配完善上篇文章中的结论
  • ClickHouse 原理解析之基础知识总结
  • 最小花费——最短路
  • Spark DataFrame join后移除重复的列
  • NextJS工程部署到阿里云linux Ecs
  • 汽车以太网IOP测试新利器
  • 高防IP是什么?如何隐藏源站IP?如何进行防护?
  • ElasticSearch---查询es集群状态、分片、索引
  • Angular 使用教程——基本语法和双向数据绑定
  • 【ASP.NET】Hello World
  • AI创作系统ChatGPT网站源码+支持最新GPT-Turbo模型+支持DALL-E3文生图/AI绘画源码
  • C#_查找图片(按键精灵找图)
  • C#中.NET Framework4.8 控制台应用通过EF访问新建数据库
  • 无防御香港服务器如何防CC