这次疫情还没有过去,但是生活依旧,还是要工作,还是要挣钱,在这里多的话不说,“武汉加油!”闲言少叙,我们直接走入主题,我们在开发复杂项目的时候,代码的迭代,修改等,都会出现UI卡顿,或者出现ANR的时候,造成的程序崩溃,等,我们如何定位到卡顿的位置等,所以国内开发者,给我送来一个福利,BlockCanary这个框架。
1.介绍 BlockCanary
BlockCanary 这个框架是android平台,非侵入式的性能监控组件。使用时提供一个抽象类,传一个上下文环境就可以使用了,使用方便.
2.UI卡顿问题
原理:
在android开发中,我们的APP的帧频性能最优的目标就是保持在60fps上。
60fps --->16ms/帧
所以我们尽量保证每次在16ms内处理完所有的CPU与GPU计算,绘制,渲染等操作,否则会造成丢帧卡顿问题。
3.UI卡顿的原因分析
1.UI线程中做耗时操作
1)主线程的作用:把事件分发给合适的view或者widget
解决办法:我们通过handler在子线程中做耗时操作
runOnUiThread方法:
View.post 方法
VIew.postDelayed方法
2.布局layout过于复杂,没办法在16ms中完成渲染
3.View的过度绘制,由于过度绘制导致在同一帧重复绘制
4.view频繁的触发measure,layout
5.内存频繁触发GC过多(在同一帧内频繁的创建临时变量)
4.BlockCanary的简单实用
1)添加开源库的依赖:
compile 'com.github.markzhai:blockcanary-android:1.5.0'
2)在Application中注册我们的BlockCanary
BlockCanary.install(this, new AppBlockContext()).start();
3).创建一个类AppBlockContext 继承 BlockCanaryContext:
public class AppBlockContext extends BlockCanaryContext {
// 实现各种上下文,包括应用标示符,用户uid,网络类型,卡慢判断阙值,Log保存位置等
/**
* Implement in your project.
*
* @return Qualifier which can specify this installation, like version + flavor.
*/
public String provideQualifier() {
return "unknown";
}
/**
* Implement in your project.
*
* @return user id
*/
public String provideUid() {
return "uid";
}
/**
* Network type
*
* @return {@link String} like 2G, 3G, 4G, wifi, etc.
*/
public String provideNetworkType() {
return "unknown";
}
/**
* Config monitor duration, after this time BlockCanary will stop, use
* with {@code BlockCanary}'s isMonitorDurationEnd
*
* @return monitor last duration (in hour)
*/
public int provideMonitorDuration() {
return -1;
}
/**
* Config block threshold (in millis), dispatch over this duration is regarded as a BLOCK. You may set it
* from performance of device.
*
* @return threshold in mills
*/
public int provideBlockThreshold() {
return 1000;
}
/**
* Thread stack dump interval, use when block happens, BlockCanary will dump on main thread
* stack according to current sample cycle.
* <p>
* Because the implementation mechanism of Looper, real dump interval would be longer than
* the period specified here (especially when cpu is busier).
* </p>
*
* @return dump interval (in millis)
*/
public int provideDumpInterval() {
return provideBlockThreshold();
}
/**
* Path to save log, like "/blockcanary/", will save to sdcard if can.
*
* @return path of log files
*/
public String providePath() {
return "/blockcanary/";
}
/**
* If need notification to notice block.
*
* @return