监控Android方法运行时的Gradle插件

监控Android方法运行时的Gradle插件,第1张

初衷

我的想法很简单,就是想知道每一个自定义方法执行时间,最好有直观的图表,而不用从大量的Profiler文件中抽丝剥茧。

阶段性成果

在开发中逐步完善,现在具备了4大基本功能

  1. 统计指定包下面的函数执行耗时
  2. 统计方法执行前后的内存数据
  3. 标记执行时间超过5000ms 或者 ANR 函数
  4. 统计电量变化

不知道有不有人感兴趣,先把源码放这里

源码:https://github.com/woshiwzy/APM_MT

效果图

整体功能

过程感悟

从下决心做这件事到现在,前后差不多一个多月,整个过程也学会了不少东西,充分的体会到

纸上得来终觉浅,绝知此事要躬行

略有所获
  • Gradle 插件开发流程
  • ASM字节码插装与代码生成技术
  • Jvmti 技术(很有用,但没用到这个项目中)
  • Python echart 绘图技术
  • Android Framework知识
  • Nexus私有仓库搭建知识
  • 私有插件与私有库托管技术
  • 其他
开发过程中遇到的最大的坑

Gradle的自带的asm相关的类混乱,导致ASM代码无法通过编译,最后下载了asm9.2 和 common-io-2.6 彻底解决。

可扩展 自定义实现

假如你想自定义收集处理机制,可以随意修改com.myapm.callback.MTCallBack的mtStart 和mtDone的具体实现。默认收集到的日志格式如下

MT_D,main,com.sand.apm.mt.App.onCreate,1652059891656,6.0MB,12.0MB,90,61,6.0MB,12.0MB,90

以逗号隔开信息分别如下

  • MT_D:代表收集到了结束信息,但是方法任然可能超过5秒甚至更多,MT_N:代表没收集到结束信息,cost会被设置成9999 方便显示
  • main:线程名
  • com.sand.apm.mt.App.onCreate:执行方法
  • 1652059891656:开始执行的时候时间戳

  • 6.0MB:开始执行时Java堆
  • 12.0MB:开始执行时的Native堆
  • 90:方法执行前电量

  • 61:方法耗时毫秒数

  • 6.0MB:方法执行后的java堆
  • 12.0MB:方法执行后的Naative堆
  • 90:方法执行后的电量
手动调用

你可以在任意方法开始处调用

long currentTimeMillis = System.currentTimeMillis();
MTCallBack.mtStart(currentTimeMillis);

方法结束处调用

 MTCallBack.mtDone(currentTimeMillis);

MT自带的机制也会给你记录下来并最终写到日志文件中

MT插件工作原理 第一步:插桩

在编译的过程中对指定路径下的类文件进行插装,例如

  public static void method1(){
      System.out.println("我是method1"); 
  }

插装后

  public static void method1(){
        long currentTimeMillis = System.currentTimeMillis();
        MTCallBack.mtStart(currentTimeMillis);
        System.out.println("我是method1"); 
        MTCallBack.mtDone(currentTimeMillis);
  }
第二步:运行时调用

其中MTCallBack是根据插件配置参数自动生成的类

MTCallBack.mtStart 和 MTCallBack.mtDone

是自动生成的静态方法,通过静态方法调用收集运行时的信息,比如方法执行时间,运行前后的内存信息,电量等。

主要的收集工作在com.sand.apm.mtlib.Statistics类中完成。

第三步:输出日志

Statistics 类中存在一个线程池,每个10秒钟把收集到日志写入到磁盘中,默认的路径是

/sdcard/Android/data/包名/files/Download/mtfiles

第四步:使用Python脚本生成渲染图

环境 python3,pyechats v1

自动化步骤

  • 通过adb pull 把日志拷贝到电脑指定的目录
  • 通过python脚本读取解析日志,生成可视图图表

整体效果图(所有图标带拖拽和缩放,手感比profiler 更佳)

统计出所有指定包下的方法执行时间

单独统计出执行时间超过5000ms的函数

统计方法运行前后的Java和Native堆

统计出方法运行前后的电量

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/905495.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-15
下一篇 2022-05-15

发表评论

登录后才能评论

评论列表(0条)

保存