前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >BlockCanary原理分析

BlockCanary原理分析

作者头像
用户1205080
发布于 2019-04-09 01:51:52
发布于 2019-04-09 01:51:52
72100
代码可运行
举报
文章被收录于专栏:编码前线编码前线
运行总次数:0
代码可运行

概述

BlockCanary是Android平台上的一个轻量的,非侵入式的性能监控组件,可以在使用应用的时候检测主线程上的各种卡顿问题,并可通过组件提供的各种信息分析出原因并进行修复。

使用

项目地址:https://github.com/markzhai/AndroidPerformanceMonitor

Step1. 配置build.gradle

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dependencies {    // most often used way, enable notification to notify block event    implementation 'com.github.markzhai:blockcanary-android:1.5.0'
    // this way you only enable BlockCanary in debug package    // debugImplementation 'com.github.markzhai:blockcanary-android:1.5.0'    // releaseImplementation 'com.github.markzhai:blockcanary-no-op:1.5.0'}

Step2. 在Application中注册

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class DemoApplication extends Application {    @Override    public void onCreate() {        // ...        // Do it on main process        BlockCanary.install(this, new BlockCanaryContext()).start();    }}

Step3. 检测结果

原理

在Android中,应用的卡顿,主要是在主线程阻塞导致的。Looper是主线程的消息调度者,所以以它为突破点。

Looper#loop()

在Looper的loop方法中,有一个Printer,它在每个Message处理的前后被调用,而如果主线程卡住了,就是 dispatchMessage里卡住了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void loop() {    // ....
    for (;;) {        // ...
        // This must be in a local variable, in case a UI event sets the logger        final 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);        }       // ...    }}

获取主线程的Looper

因为Looper在每个线程最多只有一个实例,所以只要获取到主线程的Looper,就可以设置一个自定义的Printer对象到里面。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Looper mainLooper = Looper.getMainLooper();

创建自定义Printer

在Printer的println方法去计算主线程一条Message处理的时长,当时长超过设定的阈值时就判定是卡顿了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
...@Overridepublic void println(String x) {    if (!mStartedPrinting) {        mStartTimeMillis = System.currentTimeMillis();        mStartThreadTimeMillis = SystemClock.currentThreadTimeMillis();        mStartedPrinting = true;    } else {        final long endTime = System.currentTimeMillis();        mStartedPrinting = false;        if (isBlock(endTime)) {            notifyBlockEvent(endTime);        }    }}
private boolean isBlock(long endTime) {    return endTime - mStartTimeMillis > mBlockThresholdMillis;}...

设置自定义Printer到主线程Looper

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Looper.getMainLooper().setMessageLogging(mainLooperPrinter);

流程图

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编码前线 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
BlockCanary原理分析
概述 BlockCanary是Android平台上的一个轻量的,非侵入式的性能监控组件,可以在使用应用的时候检测主线程上的各种卡顿问题,并可通过组件提供的各种信息分析出原因并进行修复。 使用 项目地址:https://github.com/markzhai/AndroidPerformanceMonitor Step1. 配置build.gradle dependencies { // most often used way, enable notification to notify block e
用户1205080
2019/04/25
1.2K0
BlockCanary原理分析
BlockCanary源码解析
如上代码中的loop()方法是Looper中的,我们的目的是监测主线程的卡顿问题,因为UI更新界面都是在主线程中进行的,所以在主线程中做耗时操作可能会造成界面卡顿,而主线程的Looper早已经在APP启动的时候Android framework里面创建了main looper,那么一个线程对应一个Looper,Looper当中有一个MessageQueue,专门用来接收Handler发送过来的msg,并且在looper()方法中循环去从MessageQueue中去取msg,然后执行,而且是顺序执行的,那么前面一个msg还没处理完,loop()就会等待它处理完了才会再去执行下一个msg,如果前面一个msg处理很慢,那就会造成卡顿了,在msg.target.dispatchMessage(msg)前有:
大大大大大先生
2018/09/04
9080
BlockCanary源码解析
Android卡顿优化 | 自动化卡顿检测方案与优化(AndroidPerformanceMonitor / BlockCanary)
当然,我们可以在logcat中定位关键词blockInfo, 看到同样的详细的信息:
凌川江雪
2020/04/09
2.6K0
Android卡顿优化 | 自动化卡顿检测方案与优化(AndroidPerformanceMonitor / BlockCanary)
面试官: 说一下你做过哪些性能优化?
之前做热修复的时候研究过 Application 的启动原理。项目中也做过一些启动优化。
做个快乐的码农
2021/12/18
1.2K0
面试官: 说一下你做过哪些性能优化?
Android 免Hook消息监控
在一些情况下,app中经常要做Hook ActivityThread、Choreographer FrameHandler,ViewRootImpl,InputMethodManager中Handler的操作,然而我们往往不可避免的就去hook替换原有的Handler或者Callback,除此之外,还有什么办法呢?
Rouse
2024/05/28
2130
Android 免Hook消息监控
深入理解Android消息机制
Android的消息机制主要说的是Handler的运行机制,相信大家对Handler已经非常熟悉了,Handler可以轻松的将一个任务切换到Handler所在的线程中去执行。最熟悉的就是我们只能在UI线程中更新UI,所以我们经常来用Handler来更新UI,但Handler并不是专门用来更新UI的。本文源码基于Android8.0。
黄林晴
2019/02/19
6600
Android App秒开的奥秘
Android App秒开,狭义的讲是指你的App的Activity从启动到显示所花费的时间在1秒以内,广义的讲是指这个过程所花费的时间越少越好。这个时间越短,你的App给用户的感觉就是响应越快,使用越流畅,用户体验更好。秒开是Android App的一个很重要的性能指标。需要我们持续的给予关注和优化。
HowHardCanItBe
2020/09/15
1.1K0
探究Android异步消息的处理之Handler详解
在学习Android的路上,大家肯定会遇到异步消息处理,Android提供给我们一个类来处理相关的问题,那就是Handler。相信大家大多都用过Handler了,下面我们就来看看Handler最简单的用法:
俞其荣
2022/07/28
5460
Android App秒开的奥秘
Android App秒开,狭义的讲是指你的App的Activity从启动到显示所花费的时间在1秒以内,广义的讲是指这个过程所花费的时间越少越好。这个时间越短,你的App给用户的感觉就是响应越快,使用越流畅,用户体验更好。秒开是Android App的一个很重要的性能指标。需要我们持续的给予关注和优化。
做个快乐的码农
2021/12/13
6540
Android App秒开的奥秘
解决Android卡顿性能瓶颈的深度探讨
在移动应用开发中,Android卡顿是一个常见但令人讨厌的问题,它可能导致用户体验下降,甚至失去用户。本文将深入探讨Android卡顿的原因,以及如何通过代码优化和性能监测来提高应用的性能。
Rouse
2023/10/27
4620
解决Android卡顿性能瓶颈的深度探讨
Android性能优化(六)之卡顿那些事
对普通用户而言,类如内存占用高、耗流量、耗电量等性能问题可能不会轻易发现,但是卡顿问题用户一定会立马直观的感受到。本文就带你一览卡顿的发生、检测、及优化。
用户2898788
2018/08/21
1.2K0
Android性能优化(六)之卡顿那些事
《广研Android卡顿监控系统》
实现背景 应用的使用流畅度,是衡量用户体验的重要标准之一。Android 由于机型配置和系统的不同,项目复杂App场景丰富,代码多人参与迭代历史较久,代码可能会存在很多UI线程耗时的操作,实际测试时候也会偶尔发现某些业务场景发生卡顿的现象,用户也经常反馈和投诉App使用遇到卡顿。因此,我们越来越关注和提升用户体验的流畅度问题。 已有方案 在这之前,我们将反馈的常见卡顿场景,或测试过程中常见的测试场景使用UI自动化来重复操作,用adb系统工具观察App的卡顿数据情况,试图重现场景来定位问题。 常用的方式是使用
腾讯Bugly
2018/03/23
4.7K2
Android Handler机制:Looper、Handler、MessageQueue、Message的关系
Handler是Android中处理异步消息的机制。Looper、Handler、MessageQueue、Message概括来说就是:Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息Message,然后回调相应的消息处理函数,而消息的创建者就是一个或多个Handler,执行完成一个消息后则继续循环。
没关系再继续努力
2021/11/18
1.3K0
你真的了解Handler吗
用法很简单,定义一个handler,重写handleMessage方法处理消息,用send系列方法发送消息。 但是主线程和新建线程用法却有点不一样!其实新线程里面的用法才是表达出完整流程的。
码上积木
2020/12/11
7060
你真的了解Handler吗
Android Handler 消息处理机制
日常开发中,一般不会在子线程中直接进行 UI 操作,大部分采取的办法是创建 Message 对象,然后借助 Handler 发送出去,再在 Handler 的 handlerMessage() 方法中获取 Message 对象,进行一系列的 UI 操作。Handler 负责发送 Message, 又负责处理 Message, 其中经历了什么 ,需要从源码中一探究竟。
用户3596197
2018/10/15
4950
面试必考体系庞大的Handler你真的都了解吗?Handler二十七问带你打破砂锅问到底!
既然它如此重要,不知对面的你了解它多深呢?今天就和大家一起打破砂锅问到底,看看Handler这口砂锅的底到底在哪里。
Android技术干货分享
2021/03/24
5670
面试必考体系庞大的Handler你真的都了解吗?Handler二十七问带你打破砂锅问到底!
Android Handler机制原理及源码解析
今天打算写一下Handler机制的原理及源码解析,Handler在我们的开发中用到的频率还是非常高的,同时这也是一个非常基础的知识点,但是即使是基础知识,有很多工作两三年的安卓开发依然是一知半解,搞不清楚原理,包括View、ViewGroup的事件分发及绘制流程。 在深入学习一下知识点之前,希望能够带着疑问去思考: 1.为什么在子线程实例化Handler会报错闪退,而主线程不会 2.为什么每个线程只能存在一个Looper和MessageQueue 3.多个Handler发送消息是怎么保证Looper轮询消息队列发送最新消息不错乱发给其他Handler的 4.子线程真的不能更新UI吗? 5.ThreadLocal的作用 ......
萬物並作吾以觀復
2018/09/13
9010
微信Android客户端的卡顿监控方案
文章开始,先聊一聊卡顿与ANR的关系:产生卡顿的根本原因是UI线程不能够及时的进行渲染,导致UI的反馈不能按照用户的预期,连续、一致的呈现。产生卡顿的原因多种多样,很难一一列举,而ANR是Google人为规定的概念,产生ANR的原因最多也只有四个。 一方面,两者息息相关,事实上,长时间的UI卡顿是导致ANR最常见的原因;但另一方面,从原理上来看,两者既不充分也不必要,是两个维度的概念。 而市面上的一些卡顿监控工具,经常被拿来监控ANR(卡顿阈值设置为5秒),这其实很不严谨:首先,5秒只是发生ANR的其中一
微信终端开发团队
2021/07/14
3.8K0
面试Handler都没答上来,你真的了解Handler吗?Handler全面解析来了!
用法很简单,定义一个handler,重写handleMessage方法处理消息,用send系列方法发送消息。 但是主线程和新建线程用法却有点不一样!其实新线程里面的用法才是表达出完整流程的。
Android技术干货分享
2020/11/27
1.2K0
面试Handler都没答上来,你真的了解Handler吗?Handler全面解析来了!
深入解析Android中Handler消息机制
Android提供了Handler 和 Looper 来满足线程间的通信。Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(MessageExchange)。Handler消息机制可以说是Android系统中最重要部分之一,所以,本篇博客我们就来深入解析Android中Handler消息机制。
老马的编程之旅
2022/06/22
5460
深入解析Android中Handler消息机制
推荐阅读
相关推荐
BlockCanary原理分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档