卡顿

Posted by ooftf on April 13, 2021

卡顿的原因有哪些

  1. 主线程执行耗时操作
  2. 频繁GC 导致stop the world
  3. 算法过于耗时
  4. 渲染过于复杂

卡顿检测

卡顿监测

监测原理

  1. 利用AOP对方法进行插桩,计算方法执行时间
  2. 循环向主线程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的代码

线上用户手机 如何监控ANR 并将 ANR 文件上传到服务器