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 源码分析实战

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小型双轮差速底盘机器人实现红外跟随功能

1. 功能说明 本文示例将实现R023样机小型双轮差速底盘跟随人移动的功能。在小型双轮差速底盘前方按下图所示安装3个 近红外传感器,制作一个红外线发射源,实现当红外发射源在机器人的检测范围内任意放置或移动时,机器人能追踪该发射源。 2. 电…

Teams Room视频会议室方案

需求背景: 适合在40平米的会议室参加Teams视频会议,会议桌周围可以坐20人,要求: 1,操作简单,一键入会Teams Room; 2,任何人带上自己的笔记本电脑,可以分享电脑画面&#…

Linux CEF(Chromium Embedded Framework)源码下载编译详细记录

Linux CEF(Chromium Embedded Framework)源码下载编译 背景 由于CEF默认的二进制分发包不支持音视频播放,需要自行编译源码,将ffmpeg开关打开才能支持。这里介绍的是Linux平台下的CEF源码下载编译过程。 前置条件 下载的过程非…

搭建Repo服务器

1 安装repo 参考&#xff1a;清华大学开源软件镜像站:Git Repo 镜像使用帮助 2 创建manifest仓库 2.1 创建仓库 git init --bare manifest.git2.2 创建default.xml文件 default.xml文件内容&#xff1a; <?xml version"1.0" encoding"UTF-8" ?…

MySQL语法2

DQL语句介绍 DQL是数据查询语言&#xff0c;用来查询数据库中表的记录 DQL-基本查询语句 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVIMG 分组后条件列表 ORDER BY 排列字段列表 LIMIT 分页参数 讲解过程&#xff1a;基本查询、条件查询…

博客网站添加复制转载提醒弹窗Html代码

网站如果是完全禁止右键&#xff08;复制、另存为等&#xff09;操作&#xff0c;对用户来说体验感会降低&#xff0c;但是又不希望自己的原创内容直接被copy&#xff0c;今天飞飞和你们分享几行复制转载提醒弹窗Html代码。 效果展示&#xff1a; 复制以下代码&#xff0c;将其…

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…

一站式印度跨境电商平台开发--多用户购物商城搭建

搭建一个一站式印度跨境电商平台开发&#xff0c;需要考虑以下几个方面&#xff1a;平台设计&#xff0c;技术架构&#xff0c;多用户购物商城搭建。 一、平台设计&#xff1a; 1. 市场调研&#xff1a;了解印度电商市场的特点和需求&#xff0c;确定目标用户群体。 2. 平台功…

【CSS3】CSS3 动画 ④ ( 使用动画制作地图热点图 )

文章目录 一、需求说明二、动画代码分析1、地图背景设置2、热点动画位置测量3、热点动画布局分析4、动画定义5、小圆点实现6、波纹效果盒子实现7、延迟动画设置 三、代码示例 一、需求说明 实现如下效果 , 在一张地图上 , 以某个位置为中心点 , 向四周发散 ; 核心 是实现 向四周…

【Java Web基础】mvn命令、Maven的安装与配置

本文极大程度上来自Maven安装(超详解)&#xff0c;但是担心安的过程中遇到什么不一样的问题&#xff0c;顺便加深印象&#xff0c;所以还是打算自己弄一篇。 目录 第一步&#xff1a;Download Maven第二步&#xff1a;解压与安装2.1 解压2.2 安装 第一步&#xff1a;Download …

Three.js纹理贴图

目录 Three.js入门 Three.js光源 Three.js阴影 Three.js纹理贴图 纹理是一种图像或图像数据&#xff0c;用于为物体的材质提供颜色、纹理、法线、位移等信息&#xff0c;从而实现更加逼真的渲染结果。 纹理可以应用于Three.js中的材质类型&#xff0c;如MeshBasicMaterial…

ClickHouse(九):Clickhouse表引擎 - Log系列表引擎

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,Kerberos安全认证,大数据OLAP体系技术栈-CSDN博客 &…

Clickhouse 数据存储

一、数据分区 数据是以分区目录的形式组织的&#xff0c;每个分区独立分开存储.这种形式&#xff0c;查询数据时&#xff0c;可以有效的跳过无用的数据文件。 1.1 数据分区的规则 分区键的取值&#xff0c;生成分区ID&#xff0c;分区根据ID决定。根据分区键的数据类型不同&am…

PoseiSwap 开启“Poseidon”池,治理体系或将全面开启

PoseiSwap曾在前不久分别以IDO、IEO的方式推出了POSE通证&#xff0c;但PoseiSwap DEX中并未向除Zepoch节点外的角色开放POSE资产的交易。而在前不久&#xff0c;PoseiSwap推出了全新的“Poseidon”池&#xff0c;该池将向所有用户开放&#xff0c;并允许用户自由的进行质押、交…

springboot(2)

springmvc 把软件系统分为3个基本部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器 &#xff08;Controller&#xff09;。 模型&#xff08;Model&#xff09;&#xff1a;Model是由一个实体Bean实现的&#xff0c;是数据的载体…

【Pytorch+torchvision】MNIST手写数字识别

深度学习入门项目&#xff0c;含代码详细解析 在本文中&#xff0c;我们将在PyTorch中构建一个简单的卷积神经网络&#xff0c;并使用MNIST数据集训练它识别手写数字。 MNIST包含70,000张手写数字图像: 60,000张用于培训&#xff0c;10,000张用于测试。图像是灰度&#xff08;即…

特殊符号的制作 台风 示例 使用第三方工具 Photoshop 地理信息系统空间分析实验教程 第三版

特殊符号的制作 首先这是一个含有字符的&#xff0c;使用arcgis自带的符号编辑器制作比较困难。所以我们准备采用Adobe Photoshop 来进行制作符号&#xff0c;然后直接导入符号的图片文件作为符号 我们打开ps&#xff0c;根据上面的图片的像素长宽比&#xff0c;设定合适的高度…

SIP协议之音/视频转换

在SIP通话应用场景中&#xff0c;有时需要在音频和视频通话中进行切换&#xff0c;这个功能实现的需要发送re-INVITE重新协商媒体&#xff0c;即重新协商媒体&#xff08;SDP)中是否允许视频。 一、实现原理 1.1 音频转视频 音频通话过程中&#xff0c;发起方重新发送INVITE消…

【力扣每日一题】2023.8.6 两两交换链表中的节点

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个链表&#xff0c;让我们两两交换相邻节点的值&#xff0c;并且不能通过修改节点内部的值来达到这一目的&#xff0c;如果可…