读者须知:本篇文章主要是收集Android重要的知识点(工作和面试常用到的),以作者知识储备找出全网问题讲解通俗易懂的答案,节约大家寻找答案时间。目的只为推广优秀的文章,帮助大家精准获取知识,涉及版权相关问题,请联系我。大家有更好的答案可以在评论区留言点赞,通过投票等方式合理展示推荐答案。
1、Android消息机制Handler
https://blog.csdn.net/zhong_zihao/article/details/107014522
Handler机制主要涉及 Message、Handler、Looper、MessageQueue、ThreadLocal
Message 可以理解为JavaBean类,封装消息的各种数据参数
MessageQueue 是消息队列,按照链表结构来存放Message
Looper 每个线程只能拥有一个Looper,且每个Looper拥有一个MessageQueue,通过自身的loop()方法
负责不断从个MessageQueue里面取出Message数据并发送给Handler的handlerMessage()方法处理
Handler 负责将Message插入到Handler对象所在线程MessageQueue,以及接受Looper传回来的消息
ThreadLocal 线程内部存储类,类似HashMap一样通过key-value 存储数据,只不过在当前线程存储的数据在
另一个线程是取不到的,数据是每个线程独立的
两个重要方法:enqueueMessage、dispachMessage
2、Android View 绘制流程
https://zhuanlan.zhihu.com/p/381485429
Android中View框架的工作机制中,主要有三个过程:
1、View树的测量(measure)Android View框架的measure机制
2、View树的布局(layout) Android View框架的layout机制
3、View树的绘制(draw)Android View框架的draw机制
View框架的工作流程为:测量每个View大小(measure)-->把每个View放置到相应的位置(layout)-->绘制每个View(draw)。
3、Android dalvik虚拟机和Art虚拟机的优化升级点
Dalvik 虚拟机是运行时将字节码转化为机器码,5.0开始废弃 全面使用ART虚拟机,Dalvik每次都要编译再运行
ART(Android RunTime 4.4引入)应用在第一次安装的时候,字节码就会预先编译成机器码,不再是执行时解释,从而优化了应用运行速度
ART应用启动快,运行快,但是耗费更多存储空间,安装时间长,总的来说ART功效就是空间换时间.
4、Android屏幕渲染机制
渲染流程线
UI对象—->CPU处理为多维图形,纹理 —–通过OpeGL ES接口调用GPU—-> GPU对图进行光栅化(Frame Rate ) —->硬件时钟(Refresh Rate)—-垂直同步—->投射到屏幕
渲染时间线
Android系统每隔16ms发出VSYNC信号(1000ms/60=16.66ms),触发对UI进行渲染, 如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着计算渲染的大多数操作都必须在16ms内完成。
5、热修复的原理,你都了解过哪几种热修复框架
热修复三种方式:代码修复、资源修复和动态链接库修复
https://www.cnblogs.com/awkflf11/p/12555425.html
热修复的原理
Android的类加载器有两种: PathClassLoader和DexClassLoader,两者的父类是BaseDexClassLoader, BaseDexClassLoader的父类是ClassLoader
其中PathDexLoader用来加载系统类和应用类;
DexClassLoader用来加载一些jar、apk、dex文件,其实jar和apk文件实际上加载的都是dex文件。
热修复原理: ClassLoader 会遍历一个由dex文件组成的数组,然后加载其中的dex文件,
我们会把正确的dex(修复过的类所在的dex)文件 插入数组的前面, 当加载器 加载到好的类文件时候就不会加载有bug的类了,就实现了热修复
基于ClassLoad的 修复实现
原理:在android中有两个常用ClassLoader,PathClassLoader加载已安装apk中class,DexClassLoader加载未安装apk或者aar中class.两个有一个共同的父类,BaseDexClassLoader,在BaseDexClassLoader->DexPathList->Element[] dexElements
中存储着apk或者aar中所有dex的集合。class加载类是从头遍历这个集合找到class就返回不会再往下找,这样我们就可以把修改好的dex查在数组的前边,让类加载器选择我们修改好的class(不知道算不算是一个bug)。
一、类加载修复方案
(1)dex分包原理
单个dex文件方法65536
(2)类加载修复方案
如果某个class类文件出现异常,将其class类修复后,将其打入patch.dex的补丁包
方案一
通过反射获取PathClassLoader的DexPathList中的Element的数组,将Patch.dex放在Element数组dexElements的第一个元素,最后将数组进行合并后并重新设置回去。在进行类加载的时候,由于ClassLoader的双亲委托机制,该类只被加载一次,也就是说Patch.dex中的Key.Class会被加载。
方案二
提供dex差量包patch.dex,将patch.dex与应用的classes.dex合并成一个完整的dex,完整dex加载后得到dexFile对象,作为参数构建一个Element对象,然后整体替换掉旧的dex-Elements数组。(Tinker)
从流程图来看,同样可以很明显的找到这种方式的特点:
优势:
1、合成整包,不用在构造函数插入代码,防止verify,verify和opt在编译期间就已经完成,不会在运行期间进行。
2、性能提高。兼容性和稳定性比较高。
3、开发者透明,不需要对包进行额外处理。
不足:
1、与超级补丁技术一样,不支持即时生效,必须通过重启应用的方式才能生效。
2、需要给应用开启新的进程才能进行合并,并且很容易因为内存消耗等原因合并失败。
3、合并时占用额外磁盘空间,对于多DEX的应用来说,如果修改了多个DEX文件,就需要下发多个patch.dex与对应的classes.dex进行合并操作时这种情况会更严重,因此合并过程的失败率也会更高。
热修复三种方式:代码修复、资源修复和动态链接库修复
一、热修复方案分类
底层替换方案:阿里的AndFix、HotFix
类加载方案:QQ空间补丁技术、微信的Tinker方案、饿了么的Amigo
二者结合:Sophix
1、类加载修复方案
如果Key.Class文件中存在异常,将该Class文件修复后,将其打入Patch.dex的补丁包
(1) 方案一:
通过反射获取到PathClassLoader中的DexPathList,然后再拿到 DexPathList中的Element数组,将Patch.dex放在Element数组dexElements的第一个元素,最后将数组进行合并后并重新设置回去。在进行类加载的时候,由于ClassLoader的双亲委托机制,该类只被加载一次,也就是说Patch.dex中的Key.Class会被加载。
(2)方案二:
提供dex差量包patch.dex,将patch.dex与应用的classes.dex合并成一个完整的dex,完整dex加载后得到dexFile对象,作为参数构建一个Element对象,然后整体替换掉旧的dex-Elements数组。(Tinker)
2、底层替换方案
(1)基本方案
主要是在Native层替换原有方法, ArtMethod结构体中包含了Java方法的所有信息,包括执行入口、访问权限、所属类和代码执行地址等。
替换ArtMethod结构体中的字段或者替换整个ArtMethod结构体,就是底层替换方案。 由于直接替换了方法,可以立即生效不需要重启。
(2)优缺点
(1)缺点
不能够增减原有类的方法和字段,如果我们增加了方法数,那么方法索引数也会增加,这样访问方法时会无法通过索引找到正确的方法。
平台兼容性问题,如果厂商对ArtMethod结构体进行了修改,替换机制就有问题。
(2)优点
Bug修复的即时性
生成的PATCH体积小,性能影响低
6、OkHttp原理
7、线程池
https://mp.weixin.qq.com/s/r_7EsctIudMb0O5-FNIWmQ
8、Android 性能分析
9、Glide的优点
支持多种图片缓存,适用于更多内容表现形式(Gif、WebP、缩略图、Video)
生命周期集成(根据Activity、Fragment的生命周期管理图片加载请求)
bitmap的复用与回收,减少系统回收压力
高效缓存策略(Picasso只会缓存原始尺寸的图片、Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式不同,使得内存开销是Picasso的一半)
10、三次握手四次挥手
https://blog.csdn.net/weixin_45393094/article/details/104965561
三次握手:
1)首先客户端发送连接请求报文
2)服务端收到连接请求后回复ACK报文,并为此次连接分配资源
3)客户端收到ACK报文后,也向服务端发送ACK报文,并分配资源,这样TCP链接就建立了
四次挥手:
第一次挥手:客户端发送一饿FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态
第二次挥手:服务端手FIN后,发送一个ACK给客户端,服务端进入CLOSE_WAIT状态
第三次挥手:服务端发送一个FIN,用来关闭服务端到客户端到数据传送,服务端进入LAST_ACK状态
第四次挥手:客户端收到FIN后,客户端进入CLOSE_WAIT状态,发送ACK给服务端,服务端进入CLOSE状态,完成四次挥手