2025年文件比较器安卓(文件比较器 compare)

文件比较器安卓(文件比较器 compare)性能优化 基本每位 Android 开发都需要考虑这个问题 像这些都是大家常用的性能检测工具 而这次我要讲的是 BlockCanary 由于这个库很久没更新了 所以可能很多人不认识 但是这并不妨碍我们去理解它的实现原理 OK 开始吹水 正文 首先 先祭出 GitHub 地址 https github com markzhai AndroidPerfo

大家好,我是讯享网,很高兴认识大家。



性能优化,基本每位 Android 开发都需要考虑这个问题。像这些都是大家常用的性能检测工具,而这次我要讲的是 BlockCanary,由于这个库很久没更新了,所以可能很多人不认识,但是这并不妨碍我们去理解它的实现原理。

OK,开始吹水正文

android 性能log_android
讯享网

首先,先祭出GitHub地址

https://github.com/markzhai/AndroidPerformanceMonitor

该库的功能主要为检测在主线程运行的操作时长,假如运行超过一定时间(默认为1000毫秒),则会记录 block 信息并提示给开发者。

集成步骤

  • 加上依赖
  • 在自定义的 Application 的 onCreate() 方法中进行初始化
  • 别忘了在 AndroidMainfest.xml 中进行 Application 绑定

具体检测效果

  • 先看看布局效果,就一个按钮
  • 对按钮进行监听并点击后睡眠 2000 毫秒
  • 点击后,BlockCanary 收集到的信息

是不是很神奇,能够定位到阻塞的位置和阻塞的时间。

android 性能log_android_02

使用总结

  • 能够计算在主线程中运行方法的时长
  • 定位运行的方法在代码上的位置

所以只要解决了以上两个问题,我们就可以自己手写个简单的 BlockCanary 了。

运行时长

em…在主线程中的运行时长…主线程…主线程…

哦!

android 性能log_android_03

由于 ActivityThread 被 MainLooper 一直死循环,所以在主线程运行操作基本都是通过 post 消息到 MessageQueue 中,由 MainLooper 取出并执行,那我们可以在执行前记录时间 A,在执行后也记录时间 B,B - A 得到的便是运行时长!

好,我们来看看 Looper 的 loop() 源码:

android 性能log_android 性能log_04

这不就是我们想要的吗,在执行方法前进行输出,在执行方法后再进行输出。

我们来看看 me.mLogging 是怎么赋值的。

me 调用 myLooper() 获取

所以 mLogging 其实就是当前 Looper 的 mLogging

OK,思路我们有了,只要调用 setMessageLogging 进行赋值,并重写 Printer 的 println() 方法,到时 Looper 就会自动调用我们的 println() 方法了

完整代码:

运行 App,点击按钮:

可以看到,只要在主线程执行方法的时候,都会调用我们的 println() 方法,但是,我们只是为了检测耗时较长的方法即可,所以多加一个拦截:

运行后,点击:

android 性能log_android 性能log_05

第一部分功能完成了,我们可以开始第二部分了:

定位代码

em…

这块代码我是从 BlockCanary 源码搬过来进行调整后,由于就是一些 SDK 方法的调度,能讲解的不多:

运行,点击后的效果:

由上可以看出,确实是输出了当前的线程的栈信息。

android 性能log_BlockCanary_06

不过,仔细看下,不太对劲啊,为什么没有定位到 clickView() 方法,不是它阻塞的吗?

android 性能log_检测_07

em…

想想也正常,因为第二次调用 println() 方法的时候,clickView() 已经执行完出栈了,自然不会输出 clickView() 的信息,所以,我们必须在 clickView() 执行的时候就要输出栈信息,也就是在 minTime 时间前,我这里选取的时间为 minTime * 0.8。怕你们忘了 minTime 是什么,提示下:

所以,我们在 printerStart 为 true 的时候,就使用 handler 发送一个 minTime * 0.8 的延迟消息,用于记录此时栈信息,假如 printerStart 为 false 的时候,执行总时间短于 minTime,我们就不输出,否则就输出栈信息。

  • 初始化Handler
  • 将获取栈消息功能单独抽取出来
  • runnable 的发送和销毁
  • 运行,点击效果:

android 性能log_BlockCanary_06

终于输出正确的栈信息了!!!


另外,这里再提个额外的信息:

在新版的 LeakCanary 中,只要进行依赖,不需要在 Application 中进行初始化就可以直接使用了!

既然我们也是要写个性能检测工具,那我们也可以参考该做法进行实现。

其实,就是在 ContentProvider 的 onCreate() 方法中进行初始化,因为 App 在启动的时候,是优先初始化 ContentProvider 再初始化 Application 的。具体代码我就不贴了,不难,只是给还未了解到这块的同学多传输些信息。


小讯
上一篇 2025-04-23 23:02
下一篇 2025-04-17 11:46

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/163557.html