数据结构
ArrayList和LinkedList的区别
ArrayList:
- 底层实现:基于数组实现,支持快速随机访问。
- 性能特点:随机访问元素的时间复杂度为O(1);在末尾添加或删除元素的时间复杂度为O(1)(平均情况),但如果数组需要动态扩容,则时间复杂度可能为O(n);在中间插入或删除元素的时间复杂度为O(n),因为需要移动元素。
- 适用场景:适合需要频繁随机访问元素,或者在末尾频繁添加或删除元素的场景。
LinkedList:
- 底层实现:基于双向链表实现,不支持随机访问。
- 性能特点:随机访问元素的时间复杂度为O(n),需要从头或尾遍历;在链表中任意位置插入或删除元素的时间复杂度为O(1),因为只需要修改指针,不需要移动元素。
- 适用场景:适合需要频繁在链表中间插入或删除元素的场景。
SparseArray的原理与应用
- 原理:
- SparseArray 是 Android 提供的一种优化过的数组实现,它使用两个数组(keys和values)来分别存储键和值,通过线性查找来实现键值对的存储和查找。
- 相比于 HashMap,SparseArray避免了自动装箱和拆箱操作,以及哈希冲突带来的开销,在键为整数的情况下,性能更优。
- 优势:
- 内存占用:SparseArray 的内存占用比 HashMap 更低,因为它避免了 HashMap 的哈希表和桶结构。
- 性能:在整数键值对的场景下,SparseArray 的查找、插入和删除操作速度更快。
- 实际场景:在 Android 中,频繁使用整数作为键值对的场景,如存储资源 ID 与对应的资源对象的映射关系时,使用 SparseArray 可以提高性能。
Android View
View的绘制过程
在Android中,视图(View)的绘制过程是一个复杂且有序的过程,主要包括三个阶段:测量(Measure)、布局(Layout) 和 绘制(Draw)。以下是这三个阶段的详细解释以及它们在视图绘制中的作用:
1. 测量(Measure)阶段
目的:确定视图的大小。
- 核心方法:measure(int widthMeasureSpec, int heightMeasureSpec)。
输入参数:widthMeasureSpec 和 heightMeasureSpec,这两个参数是父视图传递给子视图的,用于指定子视图的大小约束。 - 输出结果:通过调用setMeasuredDimension(int measuredWidth, int measuredHeight)方法,记录视图的测量宽度和高度。
测量过程:
- 自上而下:从顶层的ViewGroup开始,递归地测量所有子视图。
- 测量模式:
- MeasureSpec.EXACTLY:父视图指定了一个确切的大小,子视图必须使用这个大小。
- MeasureSpec.AT_MOST:父视图指定了一个最大值,子视图的大小不能超过这个值。
- MeasureSpec.UNSPECIFIED:父视图没有指定任何约束,子视图可以根据自己的需求选择大小。
自定义测量逻辑:
如果需要自定义测量逻辑,可以在自定义视图中重写onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法。
2. 布局(Layout)阶段
目的:确定视图在父视图中的位置。
- 核心方法:layout(int l, int t, int r, int b)。
- 输入参数:l(左边界)、t(上边界)、r(右边界)、b(下边界),这四个参数定义了视图在父视图中的位置。
- 输出结果:通过调用setFrame(int l, int t, int r, int b)方法,设置视图的最终位置和大小。
布局过程:
- 自上而下:从顶层的ViewGroup开始,递归地布局所有子视图。
- 布局顺序:父视图根据子视图的测量结果和布局参数,确定子视图的位置。
自定义布局逻辑:
如果需要自定义布局逻辑,可以在自定义视图中重写onLayout(boolean changed, int l, int t, int r, int b)方法。
3. 绘制(Draw)阶段
目的:将视图绘制到屏幕上。
- 核心方法:draw(Canvas canvas)。
- 输入参数:Canvas对象,用于绘制视图的内容。
- 输出结果:视图的内容被绘制到屏幕上。
绘制过程:
- 自上而下:从顶层的ViewGroup开始,递归地绘制所有子视图。
- 绘制顺序:父视图先绘制自己的背景,然后绘制子视图,最后绘制自己的前景。
绘制步骤:
- 绘制背景:调用drawBackground()方法。
- 绘制边框:调用drawScrollbars()方法。
- 绘制内容:调用onDraw()方法,开发者可以在这里自定义绘制逻辑。
- 绘制子视图:递归调用子视图的draw()方法。
- 绘制前景:调用drawForeground()方法。
自定义绘制逻辑:
如果需要自定义绘制逻辑,可以在自定义视图中重写onDraw(Canvas canvas)方法。
性能优化建议
- 避免过度绘制:尽量减少不必要的绘制操作,例如避免在onDraw()中执行复杂的计算或绘制。
- 使用硬件加速:在支持的设备上,启用硬件加速可以提高绘制性能。
- 合理使用视图:避免过多嵌套的ViewGroup,减少布局复杂度。
- 缓存视图:对于复杂的自定义视图,可以使用View.draw()方法将视图绘制到Bitmap中进行缓存,以减少重复绘制的开销。
通过理解Android视图的绘制过程,可以更好地优化视图的性能,提升应用的用户体验。
Framework
Lopper
https://blog.youkuaiyun.com/runrun117/article/details/79514422
AMS
https://blog.youkuaiyun.com/caohang103215/article/details/79597260
基础概念
Java基本数据类型
- 整数类型,byte、int、short、long。
- 浮点型,float、double。
- 字符型,char。
- 布尔型,boolean。
Activity的生命周期
- onCreate()
- onStart()
- onResume()
- onRestart()
- onPause()
- onStop()
- onDestory()
跳转页面Activity的生命周期
- 打开页面A
A.onCreate()->A.onStart()->A.onResume() - 由页面A到页面B
A.onPause->B.onCreate()->B.onStart()->B.onResume()->A.onStop() - 由页面B返回页面A
B.onPause()->A.onRestart()->A.onStart()->A.onResume->B.onStop()->B.onDestory()
线程安全的数据结构
https://blog.youkuaiyun.com/hellwhj/article/details/76576933
https://blog.youkuaiyun.com/u014482758/article/details/50669483
进程间的通信
- 管道
- 信号
- 消息队列
- 信号量
- 共享内存
- 套接字
参考
https://blog.youkuaiyun.com/huangqili1314/article/details/79448187