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.hqwc.cn/news/611128.html

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

相关文章

阿里云微调chatglm3-6b---只有一个python解释器但gradio要求版本不兼容怎么办

安装LLAMA参考博文http://t.csdnimg.cn/6yYwG 在用LLAMA微调大模型的时候总是出现connected error out并且出现这样的界面 这是由于LLMA所要求的gradio版本>4.0.0,<4.2.0&#xff0c;然而chatglm3-6b要求的gradio版本需要gradio3.39.0才能显示出web_demo_gradio.py渲染…

[SystemVerilog]常见设计模式/实践

常见设计模式/实践 RTL 设计&#xff08;尤其是 ASIC&#xff09;的最终目标是制作出最小、最快的电路。为此&#xff0c;我们需要了解综合工具如何分析和优化设计。此外&#xff0c;我们还关注仿真速度&#xff0c;因为等待测试运行实际上是在浪费工程精力。虽然综合和仿真工…

Android MTK 屏下指纹的调试过程记录

Demo链接 -----> https://download.csdn.net/download/u011694328/89118346 一些品牌手机都有了屏下指纹的功能&#xff0c;还算是个比较新颖的功能&#xff0c;最近有项目需要使用屏下指纹&#xff0c; 使用的是汇顶&#xff08;Goodix&#xff09;的指纹方案&#xff0c…

Ps 滤镜:表面模糊

Ps菜单&#xff1a;滤镜/模糊/表面模糊 Filter/Blur/Surface Blur 表面模糊 Surface Blur滤镜可在保留边缘清晰度的同时模糊图像&#xff0c;适用于需要在不损失重要细节的前提下减少图像杂色和噪点的场景。 ◆ ◆ ◆ 使用方法与技巧 1、可按以下步骤进行操作。 首先将“半径”…

前端和后端解决跨域问题的方法

目前很多java web开发都是采用前后端分离框架进行开发&#xff0c;相比于单体项目容易产生跨域问题。 一、跨域问题CORS 1.什么是跨域问题&#xff1f; 后端接收到请求并返回结果了&#xff0c;浏览器把这个响应拦截了。 2.跨域问题是怎么产生的&#xff1f; 浏览器基于同源…

Opentelemetry——Observability Primer

Observability Primer 可观测性入门 Core observability concepts. 可观测性核心概念。 What is Observability? 什么是可观测性&#xff1f; Observability lets us understand a system from the outside, by letting us ask questions about that system without know…

(2022级)成都工业学院数据库原理及应用实验三:数据定义语言DDL

唉&#xff0c;用爱发电连赞都没几个&#xff0c;博主感觉没有动力了 想要完整版的sql文件的同学们&#xff0c;点赞评论截图&#xff0c;发送到2923612607qq,com&#xff0c;我就会把sql文件以及如何导入sql文件到navicat的使用教程发给你的 基本上是无脑教程了&#xff0c;…

【Ubuntu】 Github Readme导入GIF

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

泽众Testone自动化测试平台,测试用例支持单个调试执行,同步查看执行日志

泽众Testone自动化测试平台之前版本&#xff0c;测试用例批量和单个执行&#xff0c;必须要通过测试集操作执行&#xff0c;操作略繁琐&#xff0c;我们通过本轮优化升级&#xff0c;测试用例直接可以单个调试执行&#xff0c;同步查看执行日志&#xff0c;操作上去繁就简&…

SpringCloud集成SkyWalking链路追踪并收集日志

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

解决PROFINET转PROFIBUS DP网关控制水处理系统通讯的问题

在工业自动化的浩渺星空中&#xff0c;PROFINET犹如一颗璀璨的明星&#xff0c;以其高效、稳定和灵活的特性&#xff0c;在以太网通信协议的舞台上大放异彩。然而&#xff0c;即便是在最明亮的星光下&#xff0c;也难免会有阴影存在。在实际应用中&#xff0c;PROFINET转PROFIB…

2024个人动态线条导航HTML源码

源码介绍 2024个人导航HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 源码下载 2024个人导航HTML源码