android启动优化
从三个方面进行优化「减少阻塞」「延迟执行」「优化效率」
1、减少Application阻塞,避免在onCreate()中执行耗时操作(如 IO、网络请求、复杂计算)
2、第三方库(如埋点、统计、推送)按需初始化,必需的库(如网络框架)用异步初始化(子线程执行)
3、优化布局绘制(减少首次绘制耗时),减少布局层级:用ConstraintLayout替代嵌套的LinearLayout/RelativeLayout(扁平化层级,减少 measure/layout 时间)。
4、启动页(SplashActivity)仅负责显示 Logo / 广告,不做复杂初始化(将逻辑移到Application或主 Activity 的子线程)。(注意)根据产品需求来定,看闪屏页广告是否停留固定的时长,启动页停留时间 = 实际初始化时间,而非固定延迟(如Thread.sleep(2000)会强制拉长启动时间)
解决启动时白屏 / 黑屏:
在启动页主题中设置windowBackground为 Logo 或背景图
android事件分发
事件分发的逻辑通过三个关键方法实现,不同组件对方法的实现不同:(如图1)

事件从 Activity 出发,自上而下传递给子 View;若子 View 不处理,事件会自下而上回溯,由父容器或 Activity 处理。
自己的理解:事件分发机制与 OkHttp 的拦截器链条在执行逻辑上确实有高度相似性,它们本质上都属于责任链模式
事件分发的核心流程是 **“自上而下传递,自下而上回溯”**,形成一条处理链:
1.起点是Activity,然后传递给顶层ViewGroup,再传递给子ViewGroup,最终到达View(链条的各个节点)。
2.每个节点(Activity/ViewGroup/View)都有两个选择:处理事件(返回true,终止传递)
或不处理(返回false,让事件继续传递给下一个节点)。
3.若所有子节点都不处理,事件会 “回溯” 给父节点,直到被处理或终止。
OkHttp 的网络请求核心是拦截器链(Interceptor Chain),其执行逻辑是 **“请求沿链传递,响应反向回溯”**
1.起点是用户发起的Request,依次经过RetryAndFollowUpInterceptor(重试与重定向)、BridgeInterceptor(补全请求头)、
CacheInterceptor(缓存处理) 、ConnectInterceptor(建立连接)等拦截器(链条的各个节点)。
2.每个拦截器有两个选择:处理部分逻辑后传递给下一个拦截器(通过chain.proceed(request)触发下一个节点),
或直接返回响应(终止传递)。
3.最终请求到达CallServerInterceptor(与服务器交互),得到Response后,再反向经过所有拦截器(如CacheInterceptor缓存响应),
最终返回给用户。
RecyclerView 四级缓存

一级:mAttachedScrap(附着的废弃视图)还 “挂” 在 RecyclerView 上的临时废弃ViewHolder(未完全脱离)。
仍附着在 RecyclerView 上,但暂时不在 “当前可见区域” 的ViewHolder。
举例: 滚动时,某个 Item 从屏幕中间慢慢滑到边缘(部分可见或刚完全不可见,但还没被 RecyclerView “剥离”)。二级:mCachedViews(缓存视图)刚完全滑出屏幕、保留数据的ViewHolder(最近被移除)。
完全滑出屏幕,且最近被移除的ViewHolder 。
保留完整数据(比如 Item 的文本、图片等),复用时有严格的position匹配(只有新 Item 的位置和缓存中ViewHolder的原位置一致时,才会直接复用,无需onBind)
三级:ViewCacheExtension(扩展缓存)开发者自定义缓存的特殊ViewHolder(按需实现)。
完全由开发者控制缓存哪些ViewHolder、如何复用。
自定义缓存逻辑(比如按id而非position匹配),适合业务中高频复用的特殊类型 Item四级:RecyclerPool(回收池)按类型分类、已清数据的通用ViewHolder(缓存池)。
按ViewType分类存储、已清除数据的ViewHolder。
不关心position,只按ViewType分组(比如文本 Item 和图片 Item 分开缓存)。
复用前必须重新绑定数据(会触发onBindViewHolder),因为数据已被清除。
使用过程:
二级缓存:默认最多缓存 2 个(可通过setItemViewCacheSize修改数量)。
四级缓存:支持跨 RecyclerView 共享(如 ViewPager 中的多个 RecyclerView 可共享同一个RecyclerPool),
减少不同列表间的ViewHolder创建开销。
减少apk体积
从四个方面进行优化「删冗余」「压资源」「优代码」「智分包」
删冗余:移除未使用的资源
压资源:图片用矢量图替代,用webp替代png/jpg
优代码:开启混淆,用轻量库(如okhttp替代volley)
智分包:架构适配,v7a,v8a单独打包
//混淆
minifyEnabled true
//Zipalign优化
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
内存优化
1、好用的内存检查工具
谈到内存优化,一些好用的内存检测工具有,LeakCanary库(自动检测内存泄露),android studio自带的profiler抓取内存快照,分析内存占比(比如发现“大图片未压缩导致bitmap占用过高”),allocation tracker(跟踪对象创建轨迹,定位频繁创建的临时对象,比如循环中重复创建Paint对象)。
2、内存占用高,内存泄漏,内存抖动三方面来说
- 内存泄露:静态引用、匿名内部类、资源未关闭
- 大内存对象优化:bitmap优化(加载时压缩,在获取图片的原始宽高信息通过设inJustDecodeBounds属性,在不加载完整图片到内存的情况下,获取图片的原始宽高信息,用RGB_565替代ARGB_8888,内存减少一半,设置inSampleSize按需缩放,比如Imageview是200x200,就加载200x200的bitmap,而非原图),还有复用内存LruCache缓存常用bitmap(比如列表图片缓存,超出容量自动回收)
- 内存抖动:短时间大量创建/回收临时对象,导致GC频繁触发(卡顿)
1、循环中不重复创建String(用StringBuilder拼接)、自定义view,ondraw方法中,Paint、Rect改为全局复用
2、针对int类型的集合,改为安卓封装的集合,SparseIntArray
3、页面/组件优化(按需加载)
- 延迟加载 viewpager用懒加载(仅加载当前页和相邻也,而非全部加载),列表用Recyclerview复用itemview而非自定义列表,避免重复创建view
HashMap理解
定位+冲突+扩容 (数组+链表+红黑树)
定位:tab[(n - 1) & hash]
冲突:hash一样equals不一样导致hash冲突,6个以下链表,6个以上红黑树
扩容:2倍,位运算