关于BlockCanary的源码分析

BlockCanar卡顿监测框架分析 Android App-BlockCanary 目录 1. BlockCanary介绍 2 1.1 功能 3 2. 为什么要使用BlockCanary? 4 3.1配置 build.gradle文件 5 3.2 新建一个类,继承自BlockCanaryContext,实现自己的监控上下文,代码示意如下 5 3.3 初始化Block的配置信息 6 3.4 检测卡顿 6 4.原... 阅读详情

关于BlockCanary的源码分析——Grass

如下是Looper的源码,应用不断地从MessageQueue中取出Message并执行。

for (;;) {
   Message msg = queue.next(); // might block
if (msg == null) {
    // No message indicates that the message queue is quitting.
    return;
}
    Printer logging = me.mLogging;
if (logging != null) {
    logging.println(">>>>> Dispatching to " + msg.target + " " +
            msg.callback + ": " + msg.what);
}
    msg.target.dispatchMessage(msg);
if (logging != null) {
    logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
    msg.recycleUnchecked();
}

在 msg.target.dispatchMessage(msg);的前后各有一次Log输出,dispatchMessage即处理一次消息,BlockCanary的原理就是计算消息处理前后的时间差,如果超出设定的阈值,则认为这是一个耗时操作。

BlockCanary.class

public void start() {
    if (!mMonitorStarted) {
        mMonitorStarted = true;
        Looper.getMainLooper().setMessageLogging(mBlockCanaryCore.monitor);
    }
}

将在BlockCanaryInternals中创建的LooperMonitor给主线程Looper的mLogging变量赋值。通过调用Looper.getMainLooper().setMessageLogging(mBlockCanaryCore.monitor);获取主线程dispatchmessage的开始和结束时间。其中,monitor变量的类型是LooperMonitor类,该类实现了Printer接口,主线程中所有的事件都会调用此方法;

@Override
public void println(String x) {
    if (mStopWhenDebugging && Debug.isDebuggerConnected()) {
       return;
    }
    if (!mPrintingStarted) {
       mStartTimestamp = System.currentTimeMillis();
       mStartThreadTimestamp = SystemClock.currentThreadTimeMillis();
       mPrintingStarted = true;
       startDump();
    } else {
       final long endTime = System.currentTimeMillis();
       mPrintingStarted = false;
       if (isBlock(endTime)) {
           notifyBlockEvent(endTime);
        }
       stopDump();
       }
}

开始会调用startDump方法开始收集信息,获取堆栈信息和CPU信息,事件结束时在 if(isBlock(endTime)) 中判断是否超过指定阻塞时间值,超过的话在notifyBlockEvent(endTime)中回调信息。而notifyBlockEvent中通过接口回调到BlockCanaryInternals类中。

public BlockCanaryInternals() {

stackSampler = new StackSampler(
       Looper.getMainLooper().getThread(),
       sContext.provideDumpInterval());

cpuSampler = new CpuSampler(sContext.provideDumpInterval());

setMonitor(new LooperMonitor(new LooperMonitor.BlockListener() {

   @Override
   public void onBlockEvent(long realTimeStart, long realTimeEnd,long threadTimeStart, long threadTimeEnd) {
       // Get recent thread-stack entries and cpu usage
       ArrayList<String> threadStackEntries = stackSampler.getThreadStackEntries(realTimeStart, realTimeEnd);
       if (!threadStackEntries.isEmpty()) {
           BlockInfo blockInfo = BlockInfo.newInstance()
                   .setMainThreadTimeCost(realTimeStart, realTimeEnd, threadTimeStart, threadTimeEnd)
                   .setCpuBusyFlag(cpuSampler.isCpuBusy(realTimeStart, realTimeEnd))
                   .setRecentCpuRate(cpuSampler.getCpuRateInfo())
                   .setThreadStackEntries(threadStackEntries)
                   .flushString();
           LogWriter.save(blockInfo.toString());

           if (mInterceptorChain.size() != 0) {
               for (BlockInterceptor interceptor : mInterceptorChain) {
                   interceptor.onBlock(getContext().provideContext(), blockInfo);
               }
           }
       }
   }
}, getContext().provideBlockThreshold(), getContext().stopWhenDebugging()));
    LogWriter.cleanObsolete();
}

BlockCanaryInternals类是事件处理事件超出设定阈值时的处理,其中的onBlockEvent方法对耗时情况进行赋值,包括方法总耗时,线程耗时,CPU是否忙,CPU占用率以及定位到具体的耗时代码行。

关于上面这段代码中的 stackSampler,是堆栈的采样,通过Main Looper获取到主线程Thread对象,调用Thread的getStackTrace方法即可获取到堆栈信息,以下是 StackSampler 中的代码:

public ArrayList<String> getThreadStackEntries(long startTime, long endTime) {
    ArrayList<String> result = new ArrayList<>();
    synchronized (sStackMap) {
        for (Long entryTime : sStackMap.keySet()) {
            if (startTime < entryTime && entryTime < endTime) {
                result.add(BlockInfo.TIME_FORMATTER.format(entryTime)
                        + BlockInfo.SEPARATOR
                        + BlockInfo.SEPARATOR
                        + sStackMap.get(entryTime));
            }
        }
    }
    return result;
}

@Override
protected void doSample() {
    StringBuilder stringBuilder = new StringBuilder();

    for (StackTraceElement stackTraceElement : mCurrentThread.getStackTrace()) {
        stringBuilder
                .append(stackTraceElement.toString())
                .append(BlockInfo.SEPARATOR);
    }

    synchronized (sStackMap) {
        if (sStackMap.size() == mMaxEntryCount && mMaxEntryCount > 0) {
            sStackMap.remove(sStackMap.keySet().iterator().next());
        }
        sStackMap.put(System.currentTimeMillis(), stringBuilder.toString());
    }
}

堆栈中耗时的代码保存在ArrayList中,堆栈则通过append拼接保存在LinkedHashMap中。

blockcanary android,ANR检测工具 blockcanary,可以检测出产生anr的地方 立即下载

相关推荐

手把手教你用UC3844设计多路输出反激电源(附PCB布局避坑指南)

本文详细介绍了使用UC3844设计多路输出反激电源的实战技巧,包括核心电路设计、变压器参数计算、PCB布局优化及EMI抑制方法。通过实验室实测数据和项目经验,帮助工程师避开常见设计陷阱,提升电源性能和可靠性。特别附赠PCB布局避坑指南,助力高效完成开关电源设计。

weixin_30300225的博客 568

BlockCanary 源码分析

在 Android 开发过程中,经常会遇到 UI 卡顿的问题,那怎么去监测 UI 的卡顿呢?。题外话:滴滴的开发辅助框架提供的卡顿监测原理与 BlockCanary 一致。BlockCanary 是一个轻量的,非侵入式的性能监控组件,目前采集了 UI 卡顿相关的线程堆栈信息和CPU 使用信息,用于分析定位问题。BlockCanary :Github 传送门 https://github.com/markzhai/AndroidPerformanceMonitor。

Elson的博客 731

Matlab安装Embedded Coder Support Package for Texas Instruments C2000 Processors教程

Matlab安装Embedded Coder Support Package for Texas Instruments C2000 Processors

m0_69133594的博客 2826

android blockcanary 原理,BlockCanary的实现原理和源码分析

简单使用implementation 'com.github.markzhai:blockcanary-android:1.5.0'实现BlockCanaryContext, 重写provideBlockThreshold()方法设置检测阈值(例如500毫秒)重写stopWhenDebugging()设置Debug模式是否启动检测stopWhenDebugging:返回 fasle: Debug启...

weixin_39607865的博客 294

2026年7月19日 从可插拔到共封装:技术路线研究报告

AI 算力的爆发正在重写数据中心光互连的技术路线。本报告对当前并存的四代光互连架构——

weixin_51184047的博客 587

Agentic AI应用架构师如何提升AI应用的灵活性

可扩展性(Scalability):快速添加新功能或扩展任务范围(如Agent从“客服”扩展到“供应链管理”);可修改性(Modifiability):调整Agent的决策逻辑或动作策略,无需重构整个系统;鲁棒性(Robustness):在环境异常或数据噪声下保持性能稳定;自适应(Self-Adaptation):自主学习新场景,无需人工干预。状态空间(S):Agent能感知的所有内部/外部状态(如用户需求、环境数据);动作空间(A):Agent能执行的所有动作(如调用工具、发送消息);

项目管理的博客 583

源码角度聊聊BlockCanary的原理,android移动应用开发答案

2.ActivityThread的内部类H 我们以Activity为例,我们知道Activity的所有的生命周期都是运行在主线程的,为什么呢? 我们来看看哈。 ActivityThread内部成员变量mH,这个mH看下代码其实就是个Handler,它的类型是有ActivityThread的内部类H决定的。 我们来看看这个H的源码。 private class H extends Handler { //定义了各种消息类型 public static final int LAUNCH_ACTIVITY

m0_65321095的博客 403

基于STM32、HAL库的ZMOD4510AI4R气体传感器驱动程序设计

ZMOD4510AI4R是Renesas公司推出的一款数字空气质量传感器,主要用于检测臭氧(O₃)和总挥发性有机化合物(TVOC)浓度。(status & 0x80)) // 检查数据就绪位。// 等待测量完成 (实际应用中应该使用非阻塞方式)// 转换为ppb (简化转换,实际应根据传感器文档校准)* @param hzmod: ZMOD4510句柄。* @param tvoc: TVOC浓度(ppb)* @param ozone: 臭氧浓度(ppb)* @param hi2c: I2C句柄。

corlin6688的博客 311

BlockCanary源码精简分析

theme: channing-cyan 卡顿的来源 通过屏幕渲染机制我们知道:Android的屏幕渲染是通过vsync实现的,软件层将数据计算好后,放入缓冲区,硬件层再从缓冲区将数据读出来绘制到屏幕上,其中渲染周期是16ms,这样我们就看到了不断变化的画面。 如果超过了16ms,就会发生卡顿,当然这个卡顿肯定是软件层的(如果发生在硬件层,换设备就行了)。那么,软件层的计算时间就需要小于...

lloydfinch's trip 181

S32K1XX Autosar开发实战|全网独家复现EB MCAL Port/Dio配置、详解引脚分层原理、实现经典跑马灯助力车载IO电控落地

在NXP S32K1XX系列车规MCU的AUTOSAR标准开发体系中,MCAL(微控制器抽象层)是软硬件解耦的核心载体,而Port端口模块与Dio数字IO模块是MCAL最基础、最核心的入门模块,也是车载指示灯、按键检测、继电器驱动、外设硬件启停控制的底层支撑。区别于传统裸机直接操作寄存器的开发方式,AUTOSAR架构采用分层隔离设计,Port负责硬件静态初始化、Dio负责动态电平操控,严格遵循车规级开发规范,杜绝硬件资源冲突、引脚配置混乱等问题。

getusushu的博客 43

构建栅格地图matlab代码

1 使用MATLAB实现地图栅格化 效果图如下所示 图1 ...

qq_59747472的博客 4518

BlockCanary源码分析

BlockCanary是一个Android平台的非侵入式的性能监控组件,应用只需要实现一个抽象类,提供一些该组件需要的上下文环境,就可以在平时使用应用的时候检测主线程上的各种卡慢问题,并通过组件提供的各种信息分析出原因并进行修复。(作者原述)很敬佩作者能够写出这么高质量的代码,BlockCanary的代码设计简洁明了,结构清晰,从唯一的一行代码install走下来,很快就能了解到整个框架的思路。去网

hanzengbo2017的博客 709

CATIA 3DEXPERIENCE R2019x VBA开发介绍

CATIA 3DEXPERIENCE R2019x VBA开发介绍 一、 什么是VBA? 【VBA的官方解释】 VBA(Visual Basic for Applications)是VisualBasic的一种宏语言,是在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展Windows的应用程序功能,特别是MicrosoftOffice软件。它也可说是一种应用程式视觉化的 Basic 脚本。 CATIA提供了多种二次开发的接口,其中包括自动化对象编程(Automation)和

WorkMan的博客 5062

Android卡顿优化:BlockCanary源码分析

背景 开源项目BlockCanary主要提供监控Android UI卡顿,并定位卡顿的代码位置的能力。 本文主要分析其设计原理和架构,我们将学习到: 如何监控UI卡顿, 如何定位产生卡顿的代码。 设计模式 Andorid系统原理 需求分析 需要了解造成卡顿的原因,并能进行模拟测试。 开发者能收到UI发生卡顿的通知 开发者能得到发生卡顿的内存快照 概要设计 详细设计 总结 ...

输出与提升 1596

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

你真的了解BlockCanary了吗?让我带你走进源码,深入了解BlockCanary的实现原理与使用

这次疫情还没有过去,但是生活依旧,还是要工作,还是要挣钱,在这里多的话不说,“武汉加油!”闲言少叙,我们直接走入主题,我们在开发复杂项目的时候,代码的迭代,修改等,都会出现UI卡顿,或者出现ANR的时候,造成的程序崩溃,等,我们如何定位到卡顿的位置等,所以国内开发者,给我送来一个福利,BlockCanary这个框架。 1.介绍 BlockCanary BlockCanary 这个框架是andr...

wk_先森的博客 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Android-BlockCanary框架源码分析

介绍 BlockCanary是Android平台上的一个轻量的,非侵入式的性能监控组件,应用只需要提供一些上下文环境就可以在使用应用的时候检测主线程上的各种卡顿问题,并通过组件提供的各种信息分析出原因并进行修复。 BlockCanary会在发生卡顿的时候记录各种信息,输出到配置目录下的文件,并弹出消息栏通知。 核心原理介绍 关于UI的操作,都是通过唯一的Handler.MainLo...

Abe的学习之路 637

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

app卡顿检测原理以及blockcanary源码分析

App检测卡顿的原理 自定义Looper中的printer public static void loop() { final Looper me = myLooper(); if (me == null) { final MessageQueue queue = me.mQueue; for (;;) { ...

achilles没有踵 735

Android UI卡顿监测框架BlockCanary原理分析

来源:https://www.jianshu.com/p/e58992439793 BlockCanary是国内开发者MarkZhai开发的一套性能监控组件,它对主线程操作进行了完全透明的监控,并能输出有效的信息,帮助开发分析、定位到问题所在,迅速优化应用。 其特点有: 非侵入式,简单的两行就打开监控,不需要到处打点,破坏代码优雅性。 精准,输出的信息可以帮助定位到问题所在(精确到行...

guquan12315的专栏 988

BlockCanary源码解析

BlockCanary源码解析 在讲解BlockCanary源码之前,我们还是需要将一些前置的知识点。本文不讲Handler的原理了,不太懂的同学自己去百度看一下吧。 什么是卡顿 在讲解卡顿问题之前,我们需要讲一下帧率这个概念。帧率是以帧称为单位的位图图像连续出现在显示器上的频率。我将一个例子,电影播放。电影其实就是很多张照片(帧)的一个集合,那为什么看起来是一个连续的过程呢?因为电影每一秒出现过的图片不止一张。实际上电影一般一秒出现的图片张数会在20-30张。假设电影一秒出现了24张图片,那么这个电影的帧

weixin_37873786的博客 2464

[源码]BlockCanary学习笔记

BlockCanary检查APP卡顿,相关使用方法以及源码学习 一、使用方法 1.添加依赖dependencies { // most often used way, enable notification to notify block event compile 'com.github.markzhai:blockcanary-android:1.5.0' // this

scau_zhangpeng的博客 649

深度剖析:Android BlockCanary 数据处理与异常识别机制全揭秘(9)

BlockCanary 是一个开源的 Android 性能监测库,它的主要功能是实时监测应用的主线程卡顿情况。该库通过巧妙地监听主线程的消息处理时间,当发现消息处理时间超过预设的阈值时,就会判定发生了卡顿事件。一旦检测到卡顿,BlockCanary 会迅速收集一系列与卡顿相关的数据,如线程堆栈信息、CPU 使用率、内存使用情况等,为开发者分析卡顿原因提供丰富的信息。

Android开发领域创作者 762

深度揭秘:Android BlockCanary 模块功能定位(1)

BlockCanary 的架构设计遵循了模块化和可扩展的理念。它将整个监测功能拆分成多个独立的模块,每个模块负责不同的功能,这样可以提高代码的可维护性和可扩展性。同时,通过合理的模块划分,使得各个模块之间的职责清晰,便于开发者进行定制和扩展。

Android开发领域创作者 1897

揭秘 Android BlockCanary 卡顿检测核心逻辑(2)

卡顿指的是应用在运行过程中出现的响应迟缓、界面不流畅的现象。具体表现可能包括界面长时间无响应、动画卡顿、点击事件延迟处理等。例如,当用户点击一个按钮,过了好几秒才看到按钮的点击效果或者执行相应的操作,这就是明显的卡顿现象。实时监测:能够实时监测应用的卡顿情况,及时发现问题。详细报告:提供详细的卡顿报告,包括卡顿发生的时间、卡顿的持续时间、线程堆栈信息等,方便开发者定位问题。可定制性:支持自定义卡顿阈值、采样频率等参数,满足不同应用的需求。轻量级:对应用的性能影响较小,不会引入过多的额外开销。初始化。

Android开发领域创作者 1015
上一篇: 写一个APP控制第三方播放器播放,以及获取正在播放的歌曲信息
Java_Grass
博客等级 码龄10年 10粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值