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

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

相关文章

16-3_Qt 5.9 C++开发指南_使用QStyle 设置界面外观_实现不同系统下的界面效果的匹配

文章目录 1. QStyle的作用(实现不同系统下的界面效果的匹配)2. Qt内置样式的使用3. 源码3.1 可视化UI设计3.2 mainwindow.cpp 1. QStyle的作用(实现不同系统下的界面效果的匹配) Qt 是一个跨平台的类库,相同的界面组件…

python版《羊了个羊》游戏开发第一天

Python小型项目实战教学课《羊了个羊》 一、项目开发大纲(初级) 版本1.0:基本开发 课次 内容 技术 第一天 基本游戏地图数据 面向过程 第二天 鼠标点击和移动 面向对象 第三天 消除 设计模式:单例模式 第四天 完整…

Database Comparer VCL for Delphi crack

Database Comparer VCL for Delphi crack 数据库比较器VCL比较并同步许多流行数据库的数据库结构(元数据)和表数据。支持的数据库列表不断更新,包括InterBase、FireBird、MySQL、MSSQL、Oracle、Sybase、PostgreSQL、DB2、PervasiveSQL、MSAccess、Paradox、DBASE以…

访问者模式——操作复杂对象结构

1、简介 1.1、概述 访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成部分。这些被访问的元素通常具有不同的类型,且不同的访问者可以对它们进行不同的访问操作。访问者模式使得用户可以在不修改现有系统的情况下扩展系…

分布式搜索ElasticSearch-ES(一)

一、ElasticSearch介绍 ES是一款非常强大的开源搜索引擎,可以帮我们从海量的数据中快速找到我们需要的内容。 ElasticSearch结合kibana、Logstash、Beats,也就是elastic stack(ELK),被广泛运用在日志数据分析,实时监控等领域。 …

Golang 包详解以及go mod

Golang 中包的介绍和定义 包(package)是多个 Go 源码的集合,是一种高级的代码复用方案,Go 语言为我们提供了 很多内置包,如 fmt、strconv、strings、sort、errors、time、encoding/json、os、io 等。 Golang 中的包可以分为三种:1、系统内置包 2、自定义包 3、第三方包…

View绘制流程-Window创建

前言: View绘制流程中,主要流程是这样的: 1.用户进入页面,首先创建和绑定Window; 2.首次创建以及后续vsync信号来临时,会请求执行刷新流程; 3.刷新流程完成后,会通知SurfaceFlin…

【机器学习1】什么是机器学习机器学习的重要性

什么是机器学习? 简而言之,机器学习就是训练机器去学习。 机器学习作为人工智能(Artificial Intelligence,AI)的一个分支,以其最基本的形式来使用算法通过从数据中获取知识来进行预测。 不同于人类通过分析大量数据手动推导规则和模型,机…

等了10年,工信部的APP备案终于来了

我是卢松松,点点上面的头像,欢迎关注我哦! 2005年3月,工信部要求所有境内网站都要进行网站备案、公安备案。 2023年8月,工信部要求所有的APP、小程序进行备案。否则…… 这绝对是一个移动互联网创业分水岭&#xff0…

Linux初识网络基础

目录 网络发展 认识“协议 ” 网络协议 OSI七层模型: TCP/IP五层(或四层)模型 网络传输基本流程 网络传输流程图: 数据包封装和封用 网络中的地址 认识IP地址: 认识MAC地址: 网络发展 1.独立…

计算机网络实验1:网络命令学习

文章目录 1. 主要教学内容2. ping命令2.1 发送ping测试报文2.2 检测TCP/IP 3. tracert命令4. ipconfig命令5. netstat命令6. arp命令7. net命令8. netsh命令 1. 主要教学内容 实验内容:学习ping、tracert、ipconfig等常用的网络命令。所需学时:1。重难点…

免费商用图片素材网站,4K高清无水印。

推荐6个图片素材网站,免费下载,还可以商用,希望对大家有帮助。 菜鸟图库 美女图片|手机壁纸|风景图片大全|高清图片素材下载网 - 菜鸟图库 网站主要是为新手设计师提供免费素材的,素材的质量都很高,类别也很多&#x…