Handler——小白能懂的原理,老鸟需要的面经

1.机制学习

1.1Handler定义

发送并处理 与线程的消息队列关联的Message和Runnable

1.2基本用法

1、Message.obtain() 从消息池取得Message

2、Handler().sendMessage(msg) 发送消息

3、Handler().post  将Runnable包装成Message发送

以下提供一个结构代码

import android.os.Handler;  
import android.os.Message;public class HandlerTestActivity extends AppCompatActivity {private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch(msg.what) {case 1:// do somethingbreak;}}};protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);setContentView(R.layout.activity_handler_test);// message形式sendMessage();// Runnable形式postRunnable();}private void sendMessage() {Message msg = Message.obtain();  msg.what = 1;  mHandler.sendMessage(msg);}private void postRunnable() {mHandler.post(new Runnable() {  @Override  public void run() {  // do something}  });}
}

1.3相关类

Message是Handler发送的消息实体

MessageQueue是用来将消息按顺序排队的队列

Looper本质就是一个循环,不停的从MessageQueue中取出消息然后处理

1.4Handler内部运行机制

  • 首先,创建一个Message开始的,交给Handler对象发送,sendMessage和sendMessageDelay最终都是在底层调用了sendMessageAtTime()方法将Message对象放入MessageQueue中的
  • 之后,由Looper的loop()循环从MessageQueue中取出Message对象,调用message.getTarget()获取到发送消息的Handler对象,然后再调用handler.dispatchMessage()方法将信息分发给对应handler执行
  • 最后,Handler在dispatchMessage()方法中判断是否有callback 存在,存在则执行callback的onMessageHandler(),最终交由Message.callback执行否则则执行handler的onMessageHandler()方法。

1.5消息队列MessageQueue存储方式

单链表结构,逻辑上属于线性结构,存储(物理)上属于链式结构

                      头尾元素易于添加和删除

                      随机存储,顺序访问

2.面试问题经验总结

  1. Handler的实现原理: Handler内部通过与Looper和MessageQueue的配合,实现了消息处理和线程间通信的功能。

  2. 子线程中能不能直接new一个Handler,为什么主线程可以: 子线程中不能直接new一个Handler,因为子线程默认没有Looper,而Handler的构造函数中需要传入一个Looper对象。主线程可以是因为主线程默认有与之关联的Looper。

  3. 主线程的Looper第一次调用loop方法,什么时候,哪个类: 主线程的Looper第一次调用loop方法是在ActivityThread类的main方法中。

  4. Handler导致的内存泄露原因及其解决方案: Handler持有外部类的引用可能导致内存泄露,解决方案可以使用弱引用或者在不需要Handler时及时removeCallbacksAndMessages(null)。

  5. 一个线程可以有几个Handler,几个Looper,几个MessageQueue对象: 一个线程可以有多个Handler,但通常只有一个Looper和一个MessageQueue对象。

  6. Message对象创建的方式有哪些 & 区别?Message.obtain()怎么维护消息池的: Message对象的创建方式包括new Message()和Message.obtain(),区别在于Message.obtain()会从消息池中获取Message对象,维护消息池是通过一些静态方法来实现的。

  7. Handler有哪些发送消息的方法: Handler的发送消息的方法包括sendMessage(Message msg)、sendMessageDelayed(Message msg, long delayMillis)、sendMessageAtTime(Message msg, long uptimeMillis)等。

  8. Handler的post与sendMessage的区别和应用场景: post方法是sendMessage方法的封装,post方法会自动将Runnable包装成Message对象发送,适用于不需要传递消息数据的情况。

  9. handler postDealy后消息队列有什么变化,假设先 postDelay 10s, 再postDelay 1s, 怎么处理这2条消息: 先postDelay 10s的消息会在消息队列中排在先,后postDelay 1s的消息会在其后。

  10. MessageQueue是什么数据结构: MessageQueue是一个基于链表的数据结构,用于存储消息队列。

  11. Handler怎么做到的一个线程对应一个Looper,如何保证只有一个MessageQueue: Handler内部通过ThreadLocal来实现一个线程对应一个Looper,并保证只有一个MessageQueue。

  12. ThreadLocal在Handler机制中的作用: ThreadLocal在Handler机制中用于存储每个线程对应的Looper对象。

  13. IdleHandler及其使用场景: IdleHandler是一种回调接口,可以在消息队列空闲时执行特定操作,常用于在UI线程空闲时执行一些耗时操作。

  14. 消息屏障、同步屏障机制: 消息屏障是指通过发送特殊的同步消息来控制消息处理的顺序,同步屏障机制用于保证一组消息按照指定的顺序执行。

  15. 子线程能不能更新UI: 子线程不能直接更新UI,必须通过Handler或者其他线程间通信的方式在主线程中更新UI。

  16. 为什么Android系统不建议子线程访问UI: 因为Android中UI操作必须在主线程中进行,子线程直接操作UI可能导致UI线程安全问题。

  17. Android中为什么主线程不会因为Looper.loop()里的死循环卡死: 主线程中Looper.loop()里的死循环会不断从消息队列中取出消息进行处理,不会导致主线程卡死。

  18. Looper.quit/quitSafely的区别: quit方法会立即终止消息循环,quitSafely会等待消息处理完毕后再退出。

  19. 通过Handler如何实现线程的切换: 可以在Handler的构造函数中传入指定的Looper对象来实现线程的切换。

  20. Handler如何与Looper关联: Handler的构造函数中需要传入一个Looper对象来与之关联。

  21. Looper如何与Thread关联: Looper是通过ThreadLocal来与线程关联的。

  22. Looper.loop()源码: Looper.loop()方法是一个无限循环,不断从消息队列中获取消息并分发处理。

  23. MessageQueue的enqueueMessage()方法如何进行线程同步的: enqueueMessage()方法内部使用了锁来实现线程同步。

  24. MessageQueue的next()方法内部原理: next()方法会阻塞等待消息到来,然后返回消息给Looper进行处理。

  25. 子线程中是否可以用MainLooper去创建Handler,Looper和Handler是否一定处于一个线程: 子线程中不能使用MainLooper创建Handler,Looper和Handler通常是处于同一个线程中。

  26. ANR和Handler的联系: 如果在主线程中有耗时操作没有及时处理,会导致ANR,通过Handler可以将耗时操作放到子线程中执行,避免ANR的发生。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/809242.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware导出虚拟机vmkd格式转换qcow2

VMware虚拟机导出qcow2格式可以上传至云服务 1、需要导出的虚拟机 2、克隆虚拟机 3、选择克隆源 4、创建完整克隆 5、完成 6、找到VMware安装路径 7、找到vmware-vdiskmanager所在路径使用cmd或Windows PowerShell进入目录 进入vmware-vdiskmanager目录 cd F:\软件\VMware Wo…

debian安装和基本使用

debian安装和基本使用 文章目录 debian安装和基本使用1. 为什么选择debian2. 如何下载Debian2.1 小型安装镜像2.2 完整安装镜像 3. Debian操作系统安装3.1 创建Debian虚拟机3.2 安装操作系统 4. Debian系统的初始设置4.1 桌面环境的配置4.2 配置网络4.3 生效网络配置4.4 配置de…

React 快速入门:掌握前端开发的核心技能

React 快速入门:掌握前端开发的核心技能 一、React 简介1.1 React 的历史1.2 React 的概念1.3 React 的特点1.4 React 的官网地址 二、开发环境搭建三、React 基础3.1 JSX3.2 组件3.3 Props3.4 State3.5 props 和 state 的区别3.6 Hook 四、React 生命周期五、添加样…

Redis Pipelining 底层原理分析及实践

作者:vivo 互联网服务器团队-Wang Fei Redis是一种基于客户端-服务端模型以及请求/响应的TCP服务。在遇到批处理命令执行时,Redis提供了Pipelining(管道)来提升批处理性能。本文结合实践分析了Spring Boot框架下Redis的Lettuce客户端和Redisson客户端对…

Unity构建详解(7)——AssetBundle格式解析

【文件格式】 文件可以分为文本文件、图片文件、音频文件、视频文件等等,我们常见的这些文件都有行业内的标准格式,其意味着按照一定的规则和规范去保存读取文件,可以获取我们想要的数据。 有些软件会有自己的文件格式,会按照其…

风储微网虚拟惯性控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 风储微网虚拟惯性控制系统simulink建模与仿真。风储微网虚拟惯性控制系统是一种模仿传统同步发电机惯性特性的控制策略,它通过集成风力发电系统、储能系统和其他分…

如何动态渲染HTML内容?用v-html!

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

计算机网络知识等汇总补充

计算机网络知识汇总补充 一、四次挥手1、为什么TCP要等待2MSL2、如果说一个系统中,有大量的time_wait和close_wait,会是什么原因? 二、你是怎么解决粘包问题?三、你觉得哪些场景适合redis四、redis的持久化策略五、你会怎么保证my…

4-云原生监控体系-Grafana-基本使用

1. 介绍 使用Grafana,您可以通过漂亮、灵活的仪表板创建、探索和共享所有数据。查询、可视化、提醒和理解您的数据,无论数据存储在何处。 图片出处: https://grafana.com/grafana/ 官方网站 2. 界面介绍 Connections 可以配置数据源&#x…

php-redis windows ,pecl 已经不维护了,解决方案:php 8.2 | 8.3+ redis extension windows

从论坛上pecl 已经不维护了,直接让大家到ci 去下载 https://stackoverflow.com/questions/76496488/redis-dll-not-found-for-php8-2/76496489#76496489 让我们找最新的一次commit ,然后又action 构建,再下载,这样的话也好&#…

Redis从入门到精通(十三)Redis分布式缓存(一)RDB和AOF持久化、Redis主从集群的搭建与原理分析

文章目录 第5章 Redis分布式缓存5.1 Redis持久化5.1.1 RDB持久化5.1.1.1 执行时机5.1.1.2 bgsave原理 5.1.2 AOF持久化5.1.2.1 AOF原理5.1.2.2 AOF配置5.1.2.3 AOF文件重写 5.1.3 RDB和AOF的对比 5.2 Redis主从5.2.1 搭建主从结构5.2.2 主从数据同步原理5.2.2.1 全量同步5.2.2.…

集群开发学习(一)(安装GO和MySQL,K8S基础概念)

完成gin小任务 参考文档: https://www.kancloud.cn/jiajunxi/ginweb100/1801414 https://github.com/hanjialeOK/going 最终代码地址:https://github.com/qinliangql/gin_mini_test.git 学习 1.安装go wget https://dl.google.com/go/go1.20.2.linu…

【Ubuntu】 Github Readme导入GIF

1.工具安装 我们使用 ffmpeg 软件来完成转换工作1.1 安装命令 sudo add-apt-repository ppa:jonathonf/ffmpeg-3sudo apt-get updatesudo apt-get install ffmpeg1.2 转换命令 (1)直接转换命令: ffmpeg -i out.mp4 out.gif(2) 带参数命令&…

【洛谷 P4017】最大食物链计数 题解(深度优先搜索+动态规划+邻接表+记忆化搜索+剪枝)

最大食物链计数 题目背景 你知道食物链吗?Delia 生物考试的时候,数食物链条数的题目全都错了,因为她总是重复数了几条或漏掉了几条。于是她来就来求助你,然而你也不会啊!写一个程序来帮帮她吧。 题目描述 给你一个…

SuperGluePretrainedNetwork调用接口版本(两个版本!)

本脚本是一个基于Python的应用,旨在演示如何使用SuperGlue算法进行图像之间的特征匹配。SuperGlue是一个强大的特征匹配工具,能够在不同的图像之间找到对应的关键点。这个工具尤其适用于计算机视觉任务,如立体视觉、图像拼接、对象识别和追踪…

RN封装三角形组件(只支持上下箭头)

import React from react; import { View, StyleSheet } from react-native;const Triangle ({ direction, width, height, color }) > {// 根据方向选择三角形的样式const triangleStyle direction up? {borderTopWidth: 0,borderBottomWidth: height,borderLeftWidth: …

docker完美安装分布式任务调度平台XXL-JOB

分布式任务调度平台XXL-JOB 1、官方文档 自己看 https://www.xuxueli.com/xxl-job/#1.1%20%E6%A6%82%E8%BF%B0 2、使用docker部署 本人使用的腾讯云,安装docker暴露一下端口,就很舒服的安装这个服务了。 docker pull xuxueli/xxl-job-admin:2.4.03…

Harmony鸿蒙南向驱动开发-PIN接口使用

功能简介 PIN即管脚控制器,用于统一管理各SoC的管脚资源,对外提供管脚复用功能:包括管脚推拉方式、管脚推拉强度以及管脚功能。 PIN接口定义了操作PIN管脚的通用方法集合,包括: 获取/释放管脚描述句柄:传…

Stable Diffusion之Ubuntu下部署

1、安装conda环境 conda create -n webui python3.10.6 2、激活环境 每次使用都要激活 conda activate webui 注意开始位置的变换 关闭环境 conda deactivate webui 3、离线下载SD 代码 https://github.com/AUTOMATIC1111/stable-diffusion-webui https://github.com/Stabilit…

10个大型语言模型(LLM)常见面试问题和答案解析

今天我们来总结以下大型语言模型面试中常问的问题 1、哪种技术有助于减轻基于提示的学习中的偏见? A.微调 Fine-tuning B.数据增强 Data augmentation C.提示校准 Prompt calibration D.梯度裁剪 Gradient clipping 答案:C 提示校准包括调整提示,尽量减少产生…