type
status
date
slug
summary
tags
category
password
icon

BlockCanary 的原理

在调⽤ start() 时,通过调⽤主线程的 Looper.setMessageLogging() ⽅法,为 Looper 的 mLogging 成员变量赋值。
在 Looper 死循环中, println ⽅法分别会在 dispatchMessage(msg) 之前和之后被调 ⽤。
所以通过⾃定义 Printer 对象,我们就可以获得 dispatchMessage 的耗时,从⽽判断出是否有应⽤卡顿。
同时 BlockCanary 还会在⼦线程中执⾏⼀个获取主线程堆栈信息的定时任务,这个任务会在 dispatchMessage 结束的时候被移除。

BlockCanary 的缺陷

  • 依靠定时获取堆栈的⽅法,定位不够精准。
  • println ⽅法中会拼接字符串对象

获取⽅法运⾏时间

  • Hugo
  • TraceView
  • Systrace
    • 使⽤ python 终端命令⽣成 Trace ⽂件 官⽅⽂档
    • 在⾼版本中,可以通过 System tracing ⽣成 trace ⽂件,⽣成的⽂件可以在 这⾥ 在线分析
在代码中主动做标记:
notion image
 

Trace 分析界⾯常⽤操作:

  • W :放⼤ (加 Shift 效果加倍)
  • S :缩⼩ (加 Shift 效果加倍)
  • A :左移
  • D :右移
  • M:标记当前选中的时间线
  • 1 :选中区域
  • 2 :拖拽
  • 3 :放⼤缩⼩
  • 4 :裁剪时间线

查看函数时间:

 

查看绘制帧:

绿⾊表示在 16ms 内完成,⻩⾊和红⾊表示超过 16 ms。

查看绘制状态:

  • 绿⾊(Running)表示运⾏中
  • 蓝⾊(Runnbale)表示可以被运⾏但是没有分配到 CPU
  • 灰⾊(⽩⾊)(Sleeping)
  • 桔红⾊(Uninterruptible Sleep)表示在执⾏ I/O 操作
 

⾃定义 Plugin

代码已上传到 github 重点:在 transform ⽅法中,遍历⽂件夹。
 
然后通过 ASM 对 class ⽂件进⾏处理
💡
ASM 是一个 Java 字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可在类被加载入虚拟机之前动态改变类行为, ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能根据要求生成新类。目前许多框架如 cglib、Hibernate、 Spring 都直接或间接使用 ASM 操作字节码。

查看 ASM 字节码的⼯具 (两个都可以)

 
notion image
💡
微信开源方案: com.tencent.matrix.plugin 其中包含 TrackCanary
💡
简单说下腾讯开源库 Matrix 获取每个方法耗时的大致原理。
通过 ASM 在字节码中给每个方法进入和退出时插入记录代码,进入/退出方法,方法标识,方法时间会被转为 long 类型记录到数组中,后续分析就可以根据方法标识从中取出数据,分析耗时
在方法调用前后插入 i/o 代码,方法调用时记录,在 dispatchMessage 耗时超阈值的时候,查表找出对应方法
💡
简单说下 BlockCanary 实现的原理?
通过调用主线程的 Looper 的 setMessageLogging 方法,传入一个 printer,以此在 disptachMessage 前后插入代码,记录 dispatchMessage 的耗时。
同时,在出现耗时方法时,通过获取线程堆栈的方式,获取主线程当前的调用栈以此来获得耗时方法
💡
简单说下你知道的有哪些分析程序运行时间的方案。 Hugo,TraceView,Systrace,TraceCanary,插桩等
HashMap 原理解析RecyclerView 原理解析
Loading...
shuouyang
shuouyang
android开发 ReactNative开发 小程序开发
最新发布
AOSP 环境搭建
2025-3-29
View 绘制流程-源码解析
2025-3-12
HTTP
2025-3-4
JVM 虚拟机
2025-2-28
蓝牙-BLE-基础
2025-2-28
从 OkHttp 的原理来看 HTTP
2025-2-19
公告
🎉热点信息🎉
--- 1 ---
Jet Brains 推出新的跨平台支持 Kotlin MultiPlatform
--- 2 ---
新的小巧便捷的依赖注入框架 Koin
--- 3 ---
新一代 API 查询语言 GraphQL