android blockcanary 原理,blockcanary源码学习随笔

blockcanary是什么?

blockcanary是国内开发者MarkZhai开发的一套性能监控组件,它对主线程操作进行了完全透明的监控,并能输出有效的信息,帮助开发分析、定位到问题所在,迅速优化应用

下图为官方原理介绍示例图:

5602ca1322b2?from=timeline&isappinstalled=0

image.png

简介

特点

非侵入式

使用简单

实时监控

提供完善的堆栈及内存信息

Android渲染机制

Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染, 如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。如果超过了16ms那么可能就出现丢帧的情况。

本文主要对blockcanary的原理进行分析,关于渲染的详细机制及优化,推荐参考如下文章:

blockcanary怎么用?

1、gradle引入库

debugImplementation 'com.github.markzhai:blockcanary-android:1.5.0'

releaseImplementation 'com.github.markzhai:blockcanary-no-op:1.5.0'

2、自定义Application并且在onCreate中进行初始化

public class ExampleApplication extends Application {

@Override public void onCreate() {

super.onCreate();

BlockCanary.install(this, new BlockCanaryContext()).start();

}

}

blockcanary核心执行流程是怎样?

blockcanary的核心原理是通过自定义一个Printer,设置到主线程ActivityThread的MainLooper中。MainLooper在dispatch消息前后都会调用Printer进行打印。从而获取前后执行的时间差值,判断是否超过设置的阈值。如果超过,则会将记录的栈信息及cpu信息发通知到前台。

关键类功能说明

说明

BlockCanary

外观类,提供初始化及开始、停止监听

BlockCanaryContext

配置上下文,可配置id、当前网络信息、卡顿阈值、log保存路径等

BlockCanaryInternals

blockcanary核心的调度类,内部包含了monitor(设置到MainLooper的printer)、stackSampler(栈信息处理器)、cpuSampler(cpu信息处理器)、mInterceptorChain(注册的拦截器)、以及onBlockEvent的回调及拦截器的分发

LooperMonitor

继承了Printer接口,用于设置到MainLooper中。通过复写println的方法来获取MainLooper的dispatch前后的执行时间差,并控制stackSampler和cpuSampler的信息采集。

StackSampler

用于获取线程的栈信息,将采集的栈信息存储到一个以key为时间戳的LinkHashMap中。通过mCurrentThread.getStackTrace()获取当前线程的StackTraceElement

CpuSampler

用于获取cpu信息,将采集的cpu信息存储到一个以key为时间戳的LinkHashMap中。通过读取/proc/stat文件获取cpu的信息

DisplayService

继承了BlockInterceptor拦截器,onBlock回调会触发发送前台通知

DisplayActivity

用于显示记录的异常信息Activity

代码执行流程

leakcanary的核心流程主要包含3个步骤。

1、init-初始化

2、monitor-监听MainLooper的dispatch时间差,推送前台通知

3、dump-采集线程栈信息及cpu信息

这里先上一下整体的流程图,建议结合源码进行查看。

5602ca1322b2?from=timeline&isappinstalled=0

image

下面我们通过上述3个步骤相关的源码来进行分析。

1、init

根据Application中的使用,我们首先看install方法

public static BlockCanary install(Context context, BlockCanaryContext blockCanaryContext) {

//BlockCanaryContext.init会将保存应用的applicationContext和用户设置的配置参数

BlockCanaryContext.init(context, blockCanaryContext);

//etEnabled将根据用户的通知栏消息配置开启

setEnabled(context, DisplayActivity.class, BlockCanaryContext.get().displayNotification());

return get();

}

接着看get方法的实现如下:

//使用单例创建了一个BlockCanary对象

public static BlockCanary get() {

if (sInstance == null) {

synchronized (BlockCanary.class) {

if (sInstance == null) {

sInstance = new BlockCanary();

}

}

}

return sInstance;

}

接着我们看BlockCanary的对象的构造方法实现如下:

private BlockCanary() {

//初始化lockCanaryInternals调度类

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值