卡顿的原因有哪些
- 主线程执行耗时操作
- 频繁GC 导致stop the world
- 算法过于耗时
- 渲染过于复杂
卡顿检测
卡顿监测
监测原理
- 利用AOP对方法进行插桩,计算方法执行时间
- 循环向主线程Looper post事件计算post和handle时间差
寻找卡顿原因
- StrictMode
- TraceView 已弃用 改为 Profiler CPU
- ANR
StrictMode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()// 检测读IO
.detectDiskWrites()// 检测写IO
.detectNetwork() // 检测网络
.penaltyLog()
.detectAll() // 检测所有问题
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects() // 检测泄漏的Sqlite对象
.detectLeakedClosableObjects()// 检测未关闭的Closable对象泄漏
.detectActivityLeaks()//检测Activity泄漏
.penaltyLog()// 打印日志
.penaltyDeath()//抛出异常
.build());
修复卡顿问题
- 主线程操作IO
- 耗时方法
- 内存不足导致频繁GC
常见卡顿原因
ANR 问题修复
什么情况下会触发 ANR
- Activity 如果5秒之心无法响应屏幕触摸事件或者键盘输入事件就会出现 ANR
- BroadcastReceiver 如果10秒内还未执行完操作也会出现 ARN
导出 ARN 文件
adb shell ls /data/anr
adb pull /data/anr/<filename>
如果报错:
1
adb: error: failed to copy '/data/anr/anr_2021-05-27-17-37-31-528' to '.\anr_2021-05-27-17-37-31-528': remote open failed: Permission denied
虽然可以看到 anr_2021-05-27-17-37-31-528文件,但是是空文件
解决方法:
如下命令使用,获取 bugreport 压缩文件
1
adb bugreport
解压后,在 \FS\data\anr 文件下能找到anr文件
在 ARN 日志中找到如下关键字
- DALVIK THREADS
- “main”
1 2 3
suspend all histogram: Sum: 161us 99% C.I. 0.092us-68us Avg: 10.733us Max: 68us DALVIK THREADS (24): "main" prio=5 tid=1 Runnable
下面所跟随的就是触发ARN的代码