Android 面试重点之Framework (Handler篇)

近期在网上看到不少Android 开发分享的面试经验,我发现基本每个面经中多多少少都有Framework 底层原理的影子。它也是Android 开发中最重要的一个部分,面试官一般会通过 Framework底层中的一些逻辑原理由浅入深进行提问,来评估应聘者的真实水平

所以对 Framework的掌握很重要,它将会是你的加分项。下面整理了一些Android Framework 常见的面试题,大家仔细的看看:

1.Handler的实现原理

从四个方面HanlderMessageMessageQueueLooper;
Handler:负责消息的发送和处理;
Message:消息对象,类似于链表的一个结点;
MessageQueue:消息队列,用于存放消息对象的数据结构;
Looper:消息队列的处理者(用于轮询消息队列的消息对象);
Handler 发送消息时调用MessageQueue的enqueueMessage插入一条信息道MessageQueue,Looper不断轮询调用MessageQueue的next方法 ,如果发现有message就调用handler的dispatchMessage,dispatchMessage被成功调用,接着调用handlerMessage()。

2.子线程中为什么不能实列Hanlder,主线程可以

因为Handler的构造方法中,会通过Looper.myLooper()获取looper对象,如果为空,则抛出异常,主线程则因为已在入口处ActivityThread的main方法中通过Looper.prepareMainLooper()获取到这个对象,并通过Looper.loop()开启循环,在子线程中若要使用handler,可先通过Looper.prepare获取到looper对象,并使用Looper.loop()开启循环

3.Handler导致的内存泄露原因极其解决方案

1.java中非静态内部类和匿名内部类都会隐式持有当前类的外部引用
2.在Activity中使用非静态内部类初始化一个Handler,此Handler就会持有当前Activity的引用。
3.一个对象被回收,那么前提它不被任何其它对象持有引用,所以当Activity页面关闭之后,存在引用关系;如果在Handler消息队列 还有未处理的消息/正在处理消息时 导致Activity不会被回收,从而造成内存泄露;
解决方案:
1.将Handler的子类设置成 静态内部类,使用WeakReference弱引用持有Activity实列
2.当外部类结束生命周期时,清空Handler内消息队列

4.一个线程可以有几个Handler,几个Looper,几个MessageQueue对象

一个线程可以有多个Handler,只有一个looper,一个MessageQueue对象。Looper.prepare()函数中知道。在Looper的prepare方法中创建了Looper对象,并放入到 ThreadLocal 中,并通过ThreadLocal来获取looper的对象,ThreadLocal的内部维护了一个ThreadLocalMap类,ThreadLocalMap是以当前Thread做为key的,因此可以得知一个线程最多只能有一个Looper对象,在Looper构造函数当中创建了MessageQueue对象,并赋值给mQueue字段,因为Looper对象只有一个,那么MessageQueue对象肯定只有一个。

5.MessageQueue是什么数据结构

内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息列表,这点于传统的队列有点儿不一样,主要区别在于Android的这个队列中消息是按照时间先后顺序来存储的,时间较早的消息,越靠近队头。有点儿先进先出的,依据的不是谁先入队,而是消息待发送的时间。

6.为什么安卓系统不建议子线程访问UI

安卓中可以有多个子线程,但是如果每个子线程都可以访问UI,则会导致界面变得混乱不堪,多个线程操作同一资源就会造成线程安全问题,当然,需要解决线程安全问题的时候,我们第一想到的可能就是加锁,但是加锁会降低运行效率,所以出于安卓性能考虑,并没有使用加锁来进行UI操作的控制。

7.子线程能不能更新UI

刷新UI,都会调用到ViewRootImpl.Android每次刷新UI的时候,最终根布局ViewRootImpl.checkThread()来检验线程是否是View的创建线程。VIewRootImpl创建的第一个笛梵,从Activity声明周期handleResumeActivity会被优先调用道,也就是说在onResume后ViewRootImpl就被创建,这个时候无法在在子线程中访问UI了,上面子线程延迟了一会,handleResumeActivity已经被调用了,所以发生了崩溃,不延迟在creae里直接设置不会崩溃 线程更新UI也行,但是只能更新自己创建的View;

8.通过Handler如何实现线程的切换

当在A线程中创建handler的时候,同时创建了MessageQueue于Looper,looper在A线程中调用loop进入一个无限的for循环从MessageQueue中取消息,当B线程调用handler发送一个message的时候,会通过msg.target.dispatchMessage(msg);将message插入到handler对应的MessageQueue中,Looper发现有message插入到MessageQueue中,便取出message执行相应的逻辑,因为Looper.loop()是在A线程中启动的,所以则会到了A线程,达到了从B线程切换到A线程的目的。

9.ANR和Handler的联系

Handler是线程间通讯的机制,Android中,网络访问,文件处理等耗时操作必须放到子线程中取执行,否则将会造成ANR异常:Application Not Response 应用程序无响应 产生ANR异常的原因:在主线程执行了耗时操作,对Activity来说,主线程阻塞5秒将造成ANR异常,对BroadcastReceiver来说,主线程阻塞10秒将会造成ANR异常。解决ANR异常的方法:耗时操作都在子线程中执行,但是不允许在子线程去修改UI,因此需要借助Handler,在子线程去修改UI的需求。

10.Looper 如何于Thread关联的

Looper与Thread之间是通过ThreadLocal关联的,这个可以看Looper.prepare()方法Looper中有一个ThreadLocal类型的sThreadLocal静态字段,Looper通过它的get和set方法来赋值和取值。由于ThreadLocal是线程绑定的,所以我们只要把Looper与ThreadLocal绑定了,那Looper和Thread也就关联上了

因此对于Android 开发而言掌握 Framework 很重要,这样有利于提高我们的面试邀约率和通过率。

如果你还没有掌握Framework,现在想要在最短的时间里吃透它,可以参考一下《Android Framework核心知识点》,里面内容包含了:Init、Zygote、SystemServer、Binder、Handler、AMS、PMS、Launcher……等知识点记录。

《Framework 核心知识点汇总手册》:https://qr18.cn/AQpN4J

Handler 机制实现原理部分:
1.宏观理论分析与Message源码分析
2.MessageQueue的源码分析
3.Looper的源码分析
4.handler的源码分析
5.总结

Binder 原理:
1.学习Binder前必须要了解的知识点
2.ServiceManager中的Binder机制
3.系统服务的注册过程
4.ServiceManager的启动过程
5.系统服务的获取过程
6.Java Binder的初始化
7.Java Binder中系统服务的注册过程

Zygote :

  1. Android系统的启动过程及Zygote的启动过程
  2. 应用进程的启动过程

AMS源码分析 :

  1. Activity生命周期管理
  2. onActivityResult执行过程
  3. AMS中Activity栈管理详解

深入PMS源码:

1.PMS的启动过程和执行流程
2.APK的安装和卸载源码分析
3.PMS中intent-filter的匹配架构

WMS:
1.WMS的诞生
2.WMS的重要成员和Window的添加过程
3.Window的删除过程

《Android Framework学习手册》:https://qr18.cn/AQpN4J

  1. 开机Init 进程
  2. 开机启动 Zygote 进程
  3. 开机启动 SystemServer 进程
  4. Binder 驱动
  5. AMS 的启动过程
  6. PMS 的启动过程
  7. Launcher 的启动过程
  8. Android 四大组件
  9. Android 系统服务 - Input 事件的分发过程
  10. Android 底层渲染 - 屏幕刷新机制源码分析
  11. Android 源码分析实战

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

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

相关文章

[每周一更]-(第57期):用Docker、Docker-compose部署一个完整的前后端go+vue分离项目

文章目录 1.参考项目2.技能点3.GO的Dockerfile配置后端的结构如图Dockerfile先手动docker调试服务是否可以启动报错 4.Vue的Dockerfile配置前端的结构如图nginx_docker.confDockerfile构建 5.docker-compose 整合前后端docker-compose.yml错误记录(1)ip端…

Android复习(Android基础-四大组件)——Service与Activity通信

我们前面学会了启动和停止服务的方法,但是服务虽然是在活动里启动的,但是启动服务之后,活动与服务之间基本没什么关系了。正常情况,我们在Activity里调用startService()方法启动MyService这个服务,然后MyService的onCr…

Games101学习笔记 - MVP矩阵

MV矩阵(模型视图变换) 目的,把摄像机通过变换移动的世界坐标远点,并且朝向与Z轴的负方向相同。这个变换就是模型试图变换。 因为移动了相机,如果想保持正确的渲染的话,那么对应的物体需要要和相机保持相对…

day23-113. 路径总和ii

113. 路径总和ii 力扣题目链接(opens new window) 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树,以及目标和 sum 22, 思路 利用…

机器学习(十八):Bagging和随机森林

全文共10000余字,预计阅读时间约30~40分钟 | 满满干货(附数据及代码),建议收藏! 本文目标:理解什么是集成学习,明确Bagging算法的过程,熟悉随机森林算法的原理及其在Sklearn中的各参数定义和使用方法 代码…

【Spring】Spring中的设计模式

文章目录 责任链模式工厂模式适配器模式代理模式模版方法观察者模式构造器模式 责任链模式 Spring中的Aop的通知调用会使用责任链模式责任链模式介绍 角色:抽象处理者(Handler)具体处理者(ConcreteHandler1)客户类角…

14.3.4 【Linux】使用 LVM thin Volume 让 LVM 动态自动调整磁盘使用率

想像一个情况,你有个目录未来会使用到大约 5T 的容量,但是目前你的磁盘仅有 3T,问题是,接下来的两个月你的系统都还不会超过 3T 的容量, 不过你想要让用户知道,就是他最多有 5T 可以使用就是了!…

Docker+rancher部署SkyWalking8.5并应用在springboot服务中

1.Skywalking介绍 Skywalking是一个国产的开源框架,2015年有吴晟个人开源,2017年加入Apache孵化器,国人开源的产品,主要开发人员来自于华为,2019年4月17日Apache董事会批准SkyWalking成为顶级项目,支持Jav…

Stable Diffusion - 俯视 (from below) 拍摄的人物图像 LoRA 与配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132192139 图像来自 哥特风格 LoRA 俯视 LoRA&#xff0c;提升视觉冲击力&#xff0c;核心配置 <lora:view_from_below:0.6>,(from below,…

工程管理系统简介 工程管理系统源码 java工程管理系统 工程管理系统功能设计em

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff…

什么是进程、线程、协程

什么是进程&#xff1f; 我们都知道计算机的核心是CPU&#xff0c;它承担了所有的计算任务&#xff1b;而操作系统是计算机的管理者&#xff0c;它负责任务的调度、资源的分配和管理&#xff0c;统领整个计算机硬件&#xff1b;应用程序则是具有某种功能的程序&#xff0c;程序…

github上有哪些值得读源码的react项目?

前言 下面是我整理的关于值得一读源码的react项目&#xff0c;希望对你有所帮助~ 1、 calcom Star: 21.6k calcom是一个开源的计算器应用程序。它提供了基本的数学运算功能&#xff0c;例如加法、减法、乘法和除法&#xff0c;还支持 科学计算、进制转换和单位转换等高级功能…

【linux-keepalive】keepalive避免单点故障,高可用配置

keepalive: [rootproxy ~]# yum install -y keepalived [rootproxy ~]# vim /etc/keepalived/keepalived.conf global_defs {router_id proxy1 //设置路由ID号vrrp_iptables //不添加任何防火墙规则 } vrrp_instance V…

c语言每日一练(4)

五道选择题 1、有以下代码&#xff0c;程序的输出结果是( ) #include <stdio.h> int main() {int a 0, b 0;for (a 1, b 1; a < 100; a){if (b > 20) break;//1if (b % 3 1)//2{b b 3;continue;}b b-5;//3}printf("%d\n", a);return 0; } A.1…

【ARM Cache 系列文章 8 -- ARM DynamIQ 技术介绍

文章目录 DynamIQ 技术背景DynamIQ技术详解DynamIQ 与 big.LITTLEDynamIQ cluster 分类硬件支持 DynamIQ为什么适合人工智能&#xff1f; DynamIQ 技术背景 2017年3月21日下午&#xff0c;ARM在北京金隅喜来登酒店召开发布会&#xff0c;正式发布了全新的有针对人工智能及机器…

IDEA创建项目常见问题

1.IDEA修改maven路径无效 创建spring项目&#xff0c;Maven导入报错&#xff0c;无法正常导入jar报&#xff0c;发现setting中设置的maven路径不是自己下载的路径&#xff0c;修改后无效。运行之后maven路径又恢复为其默认的路径 解决方案&#xff1a; 删除.mvn文件&#xff0…

dinput8.dll导致游戏打不开的解决方法,快速修复dinput8.dll文件

当你尝试启动某个游戏时&#xff0c;如果遇到dinput8.dll文件缺失或损坏的错误提示&#xff0c;可能会导致游戏无法正常运行。dinput8.dll是DirectInput API的一部分&#xff0c;它提供了游戏手柄、键盘和鼠标等输入设备的支持。本文将详细介绍dinput8.dll的作用、导致游戏无法…

Spring BeanPostProcessor 接口的作用和使用

BeanPostProcessor 接口是 Spring 框架中的一个扩展接口&#xff0c;用于在 Spring 容器实例化、配置和初始化 bean 的过程中提供自定义的扩展点。通过实现这个接口&#xff0c;您可以在 bean 实例创建的不同生命周期阶段插入自己的逻辑&#xff0c;从而实现对 bean 行为的定制…

AI 降临!!!

人的记忆是脆弱的。因此&#xff0c;个人笔记成为了我们构建第二大脑和进行知识管理的重要手段。然而&#xff0c;人工智能的崛起&#xff0c;无疑改变了我们处理信息和知识的方式。作为一名长期关注笔记方法论和 AI 软件的「效率成瘾者」和「软件发烧友」&#xff0c;我深感此…

银河麒麟高级操作系统V10助力联通云建设打出组合拳

联通云基于“双引擎基座一云多芯”为不同行业场景提供可靠、高质量的应用上云服务。在核心代码进行了全面把控&#xff0c;定制多架构芯片应用适配模版&#xff0c;开发了计算、存储、网络、中间件等组件&#xff0c;全面适配自主化服务器和操作系统&#xff0c;提供云服务器、…