腾讯Android面试:Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么

深入解析璞致PZ-ZU47DR RFSoC核心板:硬件架构与多通道ADC/DAC设计实战 本文深入解析璞致PZ-ZU47DR RFSoC核心板的硬件架构与多通道ADC/DAC设计实战。作为Xilinx Zynq UltraScale+ RFSoC系列的代表产品,PZ-ZU47DR集成了8通道5GSPS ADC和8通道9.85GSPS DAC,支持直接射频采样,大幅简化射频链路设计。文章详细介绍了其技术优势、设计挑战及实战技巧,为5G小基站、毫米波等应用场景提供高效解决方案。 阅读详情

面试官: Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么
心理分析:该问题很难被考到,但是如果一旦问到,100%会回答不上来。开发者很难注意到一个主线程的四循环居然没有阻塞住主线程

**求职者:**应该从 主线程的消息循环机制 与Linux的循环异步等待作用讲起。最后将handle引起的内存泄漏,内存泄漏一定是一个加分项

先来一份整理的面试目录
在这里插入图片描述

前言

Android的消息机制主要是指Handler的运行机制,对于大家来说Handler已经是轻车熟路了,可是真的掌握了Handler?本文主要通过几个问题围绕着Handler展开深入并拓展的了解。

站在巨人的肩膀上会看的更远。大家有兴趣的也可以到Gityuan的博客上多了解了解,全部都是干货。而且他写的东西比较权威,毕竟也是小米系统工程师的骨干成员。

Questions
  1. Looper 死循环为什么不会导致应用卡死,会消耗大量资源吗?

  2. 主线程的消息循环机制是什么(死循环如何处理其它事务)?

  3. ActivityThread 的动力是什么?(ActivityThread执行Looper的线程是什么)

  4. Handler 是如何能够线程切换,发送Message的?(线程间通讯)

  5. 子线程有哪些更新UI的方法。

  6. 子线程中Toast,showDialog,的方法。(和子线程不能更新UI有关吗)

  7. 如何处理Handler 使用不当导致的内存泄露?

回答一: Looper 死循环为什么不会导致应用卡死?

线程默认没有Looper的,如果需要使用Handler就必须为线程创建Looper。我们经常提到的主线程,也叫UI线程,它就是ActivityThread,ActivityThread被创建时就会初始化Looper,这也是在主线程中默认可以使用Handler的原因。

首先我们看一段代码

  new Thread(new Runnable() {
        @Override
        public void run() {
            Log.e("qdx", "step 0 ");
            Looper.prepare();

            Toast.makeText(MainActivity.this, "run on Thread", Toast.LENGTH_SHORT).show();

            Log.e("qdx", "step 1 ");
            Looper.loop();

            Log.e("qdx", "step 2 ");

        }
    }).start();

我们知道Looper.loop();里面维护了一个死循环方法,所以按照理论,上述代码执行的应该是 step 0 –>step 1 也就是说循环在Looper.prepare();与Looper.loop();之间。

在子线程中,如果手动为其创建了Looper,那么在所有的事情完成以后应该调用quit方法来终止消息循环,否则这个子线程就会一直处于等待(阻塞)状态,而如果退出Looper以后,这个线程就会立刻(执行所有方法并)终止,因此建议不需要的时候终止Looper。

执行结果也正如我们所说,这时候如果了解了ActivityThread,并且在main方法中我们会看到主线程也是通过Looper方式来维持一个消息循环

public static void main(String[] args) {
    Looper.prepareMainLooper();//创建Looper和MessageQueue对象,用于处理主线程的消息

    ActivityThread thread = new ActivityThread();
    thread.attach(false);//建立Binder通道 (创建新线程)

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    //如果能执行下面方法,说明应用崩溃或者是退出了...
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

那么回到我们的问题上,这个死循环会不会导致应用卡死,即使不会的话,它会慢慢的消耗越来越多的资源吗?

对于线程即是一段可执行的代码,当可执行代码执行完成后,线程生命周期便该终止了,线程退出。而对于主线程,我们是绝不希望会被运行一段时间,自己就退出,那么如何保证能一直存活呢?简单做法就是可执行代码是能一直执行下去的,死循环便能保证不会被退出,例如,binder线程也是采用死循环的方法,通过循环方式不同与Binder驱动进行读写操作,当然并非简单地死循环,无消息时会休眠。但这里可能又引发了另一个问题,既然是死循环又如何去处理其他事务呢?通过创建新线程的方式。真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死。

主线程的死循环一直运行是不是特别消耗CPU资源呢? 其实不然,这里就涉及到Linux pipe/epoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。 所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源。 Gityuan–Handler(Native层)

回答二:主线程的消息循环机制是什么?

事实上,会在进入死循环之前便创建了新binder线程,在代码

手把手教你解决Kernel panic报错:init找不到的5种排查方法(附NFS挂载实战) 本文深入解析了Linux系统启动时出现“Kernel panic - not syncing: No working init found”报错的根本原因,并提供了五种系统性的排查方法。文章结合NFS挂载根文件系统的实战场景,详细阐述了从动态链接库依赖、内核引导参数、NFS权限配置、文件系统完整性到内核配置干扰的完整排查路径,帮助开发者快速定位并解决这一常见的系统启动故障。 阅读详情

相关推荐

DCM、PLL以及DLL等概念及详情

介绍DLL、PLL以及DCM的概念,总结其模块构成、工作原理、相互之间的差异与各自优势。

CLL_caicai的博客 8337

IAR for ARM 搭建STM32F103C8T6工程模板(实战指南)

本文详细介绍了如何在IAR for ARM开发环境中为STM32F103C8T6微控制器搭建完整的工程模板。从环境准备、固件库获取、目录结构设计到工程配置与编译调试,提供了实战指南和常见问题解决方案,帮助开发者快速建立稳定的STM32开发环境。

fun88的博客 987

dToF直方图之美_deadtime死区时间

IMX459的死区时间可以在6ns,这个时间是什么级别,车载激光雷达激光器的光脉宽一般都在4ns以上,也就是这个时间贴近去SPAD的死区时间,这就导致了pile up会非常弱,不会有太多数量的光子计数堆积,加上某些SPAD设计,对TDC有一些更深入的考量,所以不需要去校正pile up算法。Sensor层面决定了pile up的复杂程度,如果一个dToF的SPAD一致性非常好,那么pile up校正可以简单到极致,也就是一句代码的事,比如IMX611,优秀到不需要后端去考虑校正pile up。

dream it possible 1433

在鸿蒙中使用AVPlayer完成视频的播放【坚果派】

播放的全流程包含:创建AVPlayer,设置播放资源和窗口,设置播放参数(音量/倍速/缩放模式),播放控制(播放/暂停/跳转/停止),重置,销毁资源。5.准备播放:调用prepare(),AVPlayer进入prepared状态,此时可以获取duration,设置缩放模式、音量等。8.退出播放:调用release()销毁实例,AVPlayer进入released状态,退出播放。6.视频播控:播放play(),暂停pause(),跳转seek(),停止stop() 等操作。今天我们来看一下视频如何正常播放。

坚果的博客 4054

华为ensp、思科eve、华为ensp pro中通过cloud桥接本地网络和联通互联网的方法

华为ensp、思科eve中通过cloud桥接本地网络和联通互联网的方法

suofen9703的博客 409

RK3588 MPP,RGA,DRM,QT之RGA

RK3588多路视频采用RGA来进行混合成一帧

dreamliweiming的博客 4264

【知识分享】CAN总线中终端网络的重要性

P沟道和N沟道晶体管的漏源通态电阻匹配良好时,形成的CANH和CANL信号匹配良好;如果驱动器的一半具有比另一半低得多的导通状态电阻,那么总线共模电压将从VCC/2的显性状态偏离,并回到VCC/2的隐性状态,这将导致每一次状态转换都会伴随着共模电压噪声,从而导致更高水平的传导和辐射能量发射。

一只豌豆象的博客 1543

基于深度学习的茶叶等级检测识别系统:YOLOv10 + UI界面 + 数据集

YOLOv10是YOLO系列的最新版本,继承了YOLO模型的优点,并对速度和精度进行了优化。YOLOv10在目标检测中使用卷积神经网络(CNN)作为基础,通过改进网络结构和优化训练策略,实现了在更低的延迟下进行高精度的目标检测。本文详细介绍了基于YOLOv10的茶叶等级检测与识别系统的设计与实现过程。我们从数据集准备、模型训练与推理、UI界面设计等多个方面进行了详细讲解,并给出了相应的代码实现。通过本系统,我们可以高效地自动检测茶叶的等级,并通过UI界面直观地展示结果。

YOLO 763

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: 阿里巴巴面试:Binder通信原理与机制
下一篇: 腾讯面试合集:热修复连环炮(热修复是什么 有接触过tinker吗,tinker原理是什么)
初壹十五a
博客等级 码龄8年 146粉丝 257原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值