1、什么是ANR?
ANR = Application Not Responding,应用无响应。
一句话解释
Android 系统检测到主线程(UI 线程)长时间卡住不响应 ,超过规定时间阈值,系统弹出应用无响应弹窗,可选择等待或强制关闭。
触发本质
Android 所有 UI 刷新、事件分发都在主线程 ;一旦主线程被耗时操作阻塞,没法处理用户点击、绘制界面,系统判定卡死,就触发 ANR。
常见触发场景阈值
- 按键 / 触摸事件(主线程阻塞):5 秒 没响应 → ANR
- 广播
onReceive:前台 10s / 后台 60s - Service 回调:20 秒 处理不完
核心产生原因
- 主线程做耗时操作网络请求、文件 IO、数据库查询、循环计算、解析大 JSON / 大图。
- 主线程死锁 / 等待同步锁不当、Handler 死循环、等待子线程未唤醒。
- UI 卡顿绘制超时布局嵌套过深、View 过度绘制、自定义 View onDraw 耗时。
- 广播 / 服务处理耗时onReceive、Service onCreate/onStartCommand 写耗时逻辑。
- 内存问题频繁 GC、内存泄漏导致卡顿、主线程调度被抢占。
通用解决方法
- 耗时全丢子线程IO、网络、数据库、复杂计算 全部放到子线程 / 协程 / 线程池。
- 主线程只做 UI 刷新只负责控件赋值、跳转、弹窗,不做任何阻塞操作。
- 优化布局与绘制减少布局嵌套、去掉过度绘制、onDraw 避免创建对象、少做耗时运算。
- 广播 / 服务轻量化onReceive 只发消息、启线程、抛事件,不做耗时业务。
- 避免主线程死锁合理使用同步锁,不主线程等待子线程结果。
- 内存优化解决内存泄漏、大图压缩复用、减少频繁对象创建,降低 GC 卡顿。
- ANR 日志定位 查看
anr/traces.txt,定位卡死的主线程堆栈,精准改代码。
2、Activity的启动流程?
Activity 三种启动流程:冷启动、温启动、热启动
1. 冷启动
场景 :App 完全没开过、后台被杀、手机重启后第一次点开。过程 :系统先创建进程 → 初始化 App → 初始化 Application → 走 Activity 完整生命周期(onCreate→onStart→onResume)。特点 :最慢,从头到尾全部重新来,啥都要初始化一遍。
2. 温启动
场景 :App 后台还在,但目标 Activity 已经被销毁了(内存不足被系统回收)。过程 :进程还在、不用重新创建 ,直接重建目标 Activity,走 onCreate 等流程,不用初始化 Application。特点:速度中等,进程保留,只重建页面。
3. 热启动
场景 :App 在后台挂着,页面没被销毁,只是切到后台了。过程 :进程、Activity 都还活着 ,直接从后台切到前台,只走 onStart → onResume,不走 onCreate。特点 :最快,不用重建任何东西,直接唤醒页面。
一句话极简区分
- 冷启动:App 彻底死了,从头新建进程 + 页面,最慢;
- 温启动:App 进程还在,页面死了,只重建页面;
- 热启动:App 和页面都活着,只是藏后台,直接唤醒,最快。
3、冷启动的原理?
什么是冷启动
App完全没运行过 、后台被系统彻底杀掉、手机重启后第一次点开,就是冷启动,是最慢的一种启动。
冷启动完整流程(通俗版)
- 第一步:系统创建 App 进程 你点击图标,系统发现这个 App连进程都没有,先单独给它开辟一个新进程。
- 第二步:创建并初始化 Application 进程建好后,先跑 Application ,执行它的构造方法、
onCreate,全局配置、SDK 初始化都在这里走一遍。 - 第三步:启动目标 Activity Application 初始化完,系统开始创建目标 Activity,走完整生命周期:
onCreate → onStart → onResume - 第四步:加载布局、绘制页面解析 XML 布局、加载图片、渲染 UI,最后把页面显示到屏幕上。
核心特点
- 要经历:创建进程 → 初始化 Application → 初始化 Activity → 加载布局渲染 UI 全套流程。
- 啥都是从零新建 ,没有任何缓存复用,所以最慢、最容易卡顿。
为啥冷启动容易慢?
Application 里塞太多 SDK 初始化、主线程做耗时操作、布局太复杂、Activity onCreate 写太多耗时逻辑,都会拖慢冷启动。
4、如何优化Activity的启动速度?
一、先懂核心
Activity 启动慢,90% 都是主线程堵车了,初始化、加载数据、布局太复杂,卡住 UI 渲染。
二、具体优化方法(按优先级)
1. 优化 Application 初始化
- 别在 Application 主线程做耗时操作 第三方 SDK、初始化、数据库、大图预加载,全部丢子线程、懒加载。
- 非必要 SDK 延迟初始化,用到再初始化,不要一打开 App 全加载。
2. 优化布局 XML
- 减少布局嵌套,别多层 LinearLayout 嵌套,多用 ConstraintLayout。
- 减少冗余 View,页面不用的控件删掉,不要写大量默认隐藏的 View。
- 用 ViewStub 延迟加载 不立即显示的布局(详情页、弹窗布局)。
- 避免 过度绘制、自定义 View onDraw 做耗时计算、频繁 new 对象。
3. 优化 Activity 生命周期
- onCreate 只做必须的 网络请求、大数据解析、复杂业务逻辑不要放 onCreate,丢子线程 / 协程。
- 能延迟加载的内容,等页面渲染完再加载,不要阻塞首屏。
- 避免在主线程做 IO、数据库、循环计算、解析大 JSON。
4. 首屏体验优化
- 做启动页占位图,避免白屏、黑屏,视觉上感觉秒开。
- 首屏先加载骨架屏 / 默认占位,数据回来再刷新,不阻塞页面显示。
5. 资源与图片优化
- 图片压缩、用 WebP,避免大图一次性加载进内存。
- 用图片框架异步加载,不要自己在主线程解码图片。
6. 其他小优化
- 减少 Activity 启动时的 Intent 大数据传递,避免 Binder 卡顿。
- 避免内存泄漏、频繁 GC,GC 频繁也会拖慢启动。
- 合理使用 懒加载、按需初始化,不用不创建。
三、一句话总结
- App 全局别在 Application 瞎初始化
- 布局别嵌套、冗余控件砍掉、ViewStub 懒加载
- onCreate 不做耗时,网络 / IO 全丢子线程
- 首屏做占位,视觉秒开