【android每日一问】怎么检测UI卡顿?(线上及线下)(1)

这篇具有很好参考价值的文章主要介绍了【android每日一问】怎么检测UI卡顿?(线上及线下)(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

msg.target.dispatchMessage(msg);

if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}


}
}

注意到两个很关键的地方是logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what);logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);这两行代码,它调用的时机正好在dispatchMessage(msg)的前后,而主线程卡也就是在dispatchMessage(msg)卡住了。

BlockCanary的流程图

(图片来自网络)

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

BlockCanary就是通过替换系统的Printer来增加了一些我们想要的堆栈信息,从而满足我们的需求。

替换原有的Printer是通过以下方法:

Looper.getMainLooper().setMessageLogging(mainLooperPrinter);

并在mainLooperPrinter中判断start和end,来获取主线程dispatch该message的开始和结束时间,并判定该时间超过阈值(如2000毫秒)为主线程卡慢发生,并dump出各种信息,提供开发者分析性能瓶颈。如下所示:

@Override
public void println(String x) {
if (!mStartedPrinting) {
mStartTimeMillis = System.currentTimeMillis();
mStartThreadTimeMillis = SystemClock.currentThreadTimeMillis();
mStartedPrinting = true;
startDump();
} else {
final long endTime = System.currentTimeMillis();
mStartedPrinting = false;
if (isBlock(endTime)) {
notifyBlockEvent(endTime);
}
stopDump();
}
}

private boolean isBlock(long endTime) {
return endTime - mStartTimeMillis > mBlockThresholdMillis;
}

  • BlockCanary dump的信息包括如下:

基本信息:安装包标示、机型、api等级、uid、CPU内核数、进程名、内存、版本号等
耗时信息:实际耗时、主线程时钟耗时、卡顿开始时间和结束时间
CPU信息:时间段内CPU是否忙,时间段内的系统CPU/应用CPU占比,I/O占CPU使用率
堆栈信息:发生卡慢前的最近堆栈,可以用来帮助定位卡慢发生的地方和重现路径

  • 获取系统状态信息是通过如下代码实现:

threadStackSampler = new ThreadStackSampler(Looper.getMainLooper().getThread(),
sBlockCanaryContext.getConfigDumpIntervalMillis());
cpuSampler = new CpuSampler(sBlockCanaryContext.getConfigDumpIntervalMillis());

下面看一下ThreadStackSampler是怎么工作的?

protected void doSample() {
// Log.d(“BlockCanary”, “sample thread stack: [” + mThreadStackEntries.size() + ", " + mMaxEntryCount + “]”);
StringBuilder stringBuilder = new StringBuilder();

// Fetch thread stack info
for (StackTraceElement stackTraceElement : mThread.getStackTrace()) {
stringBuilder.append(stackTraceElement.toString())
.append(Block.SEPARATOR);
}
// Eliminate obsolete entry
synchronized (mThreadStackEntries) {
if (mThreadStackEntries.size() == mMaxEntryCount && mMaxEntryCount > 0) {
mThreadStackEntries.remove(mThreadStackEntries.keySet().iterator().next());
}
mThreadStackEntries.put(System.currentTimeMillis(), stringBuilder.toString());
}
}

直接去拿主线程的栈信息, 每半秒去拿一次, 记录下来, 如果发生卡顿就显之显示出来 拿CPU的信息较麻烦, 从/proc/stat下面拿实时的CPU状态, 再从/proc/" + mPid + "/stat中读取进程时间, 再计算各CPU时间占比和CPU的工作状态.

基于系统WatchDog原理来实现

  • 启动一个卡顿检测线程,该线程定期的向UI线程发送一条延迟消息,执行一个标志位加1的操作,如果规定时间内,标志位没有变化,则表示产生了卡顿。如果发生了变化,则代表没有长时间卡顿,我们重新执行延迟消息即可。

public class WatchDog {
private final static String TAG = “budaye”;
//一个标志
private static final int TICK_INIT_VALUE = 0;
private volatile int mTick = TICK_INIT_VALUE;
//任务执行间隔
public final int DELAY_TIME = 4000;
//UI线程Handler对象
private Handler mHandler = new Handler(Looper.getMainLooper());
//性能监控线程
private HandlerThread mWatchDogThread = new HandlerThread(“WatchDogThread”);
//性能监控线程Handler对象
private Handler mWatchDogHandler;

//定期执行的任务
private Runnable mDogRunnable = new Runnable() {
@Override
public void run() {
if (null == mHandler) {
Log.e(TAG, “handler is null”);
return;
}
mHandler.post(new Runnable() {
@Override
public void run() {//UI线程中执行
mTick++;
}
});
try {
//线程休眠时间为检测任务的时间间隔
Thread.sleep(DELAY_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
//当mTick没有自增时,表示产生了卡顿,这时打印UI线程的堆栈
if (TICK_INIT_VALUE == mTick) {
StringBuilder sb = new StringBuilder();
//打印堆栈信息
StackTraceElement[] stackTrace = Looper.getMainLooper().getThread().getStackTrace();
for (StackTraceElement s : stackTrace) {
sb.append(s.toString() + “\n”);
}
Log.d(TAG, sb.toString());
} else {
mTick = TICK_INIT_VALUE;
}
mWatchDogHandler.postDelayed(mDogRunnable, DELAY_TIME);
}
};
/**

  • 卡顿监控工作start方法
    */
    public void startWork(){
    mWatchDogThread.start();
    mWatchDogHandler = new Handler(mWatchDogThread.getLooper());
    mWatchDogHandler.postDelayed(mDogRunnable, DELAY_TIME);
    }
    }
  • 调用startWork即可开启卡顿检测。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

最后

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

【android每日一问】怎么检测UI卡顿?(线上及线下)(1),程序员,android,ui

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!文章来源地址https://www.toymoban.com/news/detail-852035.html

存中…(img-6pQWATYk-1712829469516)]

[外链图片转存中…(img-m2o8EXLQ-1712829469516)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

到了这里,关于【android每日一问】怎么检测UI卡顿?(线上及线下)(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Kafka每日一问】Kafka重平衡逻辑是什么样的?

    在Kafka中,消费者重平衡(Consumer Rebalance)是指消费者加入或退出消费者组时,以及消费者组内的消费者发生宕机、重启等异常情况时,通过重新分配分区(Partition)来实现消费者负载均衡的过程。Kafka消费者重平衡是Kafka中核心的功能之一,能够有效地保证消费者组内消息的

    2024年01月17日
    浏览(43)
  • 【前端每日一问002】jquery中each与data方法的用法与概念

    在 jQuery 中, .each() 方法和 .data() 方法都是常用的工具。这两个方法的用法和概念如下: .each() 方法是 jQuery 对象的方法,用于遍历匹配元素集合中的所有元素,并对每个元素执行一个回调函数。该方法的语法如下: 其中, selector 是用于匹配元素的选择器,可以是任何 jQuer

    2024年02月06日
    浏览(37)
  • 【Kafka每日一问】Kafka消费者故障,出现活锁问题如何解决?

    在Kafka中,消费者的“活锁”通常是指消费者实例持续失败并重新加入消费者组,但却始终无法成功处理消息。这种现象可能会导致消费者组不断触发重平衡(rebalance),而消息却没有被实际消费。以下是一些解决或缓解活锁问题的策略: 1. 优化消息处理逻辑 消费者可能由于

    2024年01月20日
    浏览(44)
  • 刚面试了一位5年的Android开发,一问三不知,他还反怼我...

    最近帮部门主管面试了很多人,从简历上看这些人的工作年限都不短,但做的都是一些传统的项目,想做现在大环境越来越难,大家找工作都不容易,就打算见一见。 在沟通中发现,由于年限不小,他们的定位基本都是高级及以上,毕竟,年限摆在那里,面个中级也不体面。

    2024年02月04日
    浏览(74)
  • Android Studio的新界面New UI,怎么切换回老界面

    最近更新了Android Studio,发现界面风格不一样了,有点像Windows 11的风格,详见图片 不习惯,还是习惯老界面,菜单File-Setting,在Setting界面将Enable new UI的勾去掉,点OK,重启Android Studio,熟悉的界面又回来了。

    2024年02月19日
    浏览(40)
  • 自己架设的传奇会卡顿、掉线是什么原因?传奇卡顿怎么解决?

    因为平时接触传奇的用户比较多,所以也会遇到架设的传奇出现卡顿、掉线的情况,这究竟是为什么呢?飞飞总结了以下原因和解决方案希望可以帮助到你~ 首先我们结合情况来,刚架设好的服,测试时就遇到了卡顿、掉线的情况,大概率是和游戏设置有关系的,我们可以先

    2024年02月15日
    浏览(148)
  • 服务器卡顿怎么查找原因?

    虽然服务器出现卡顿的现象比较少见,但也不排除出现的可能,而服务器一旦出现卡顿,造成的后果会严重的多。这里分享点笔记,希望有所帮助 1. 性能评估: 首先,对服务器的性能进行全面评估。检查 CPU 使用率、内存占用、磁盘读写速度等关键性能指标,确认是否存在明

    2024年02月11日
    浏览(48)
  • 电脑重装系统后卡顿怎么办?教你快速解决电脑卡顿问题

    ​Win10电脑卡顿怎么办?许多用户在使用电脑的过程中发现,随着使用时间的增加,电脑会越来越卡顿。有些小伙伴就会选择重装电脑系统,那么我们在重装电脑之后要进行什么操作才能让电脑不卡顿呢? 操作方法: 优化一、常用图标发送到桌面 有些WIN10系统安装完成之后,

    2024年02月09日
    浏览(35)
  • iOS UI掉帧和卡顿优化解决方案记录

    UI卡顿原理 在 VSync 信号到来后,系统图形服务会通过 CADisplayLink 等机制通知 App,App 主线程开始在 CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等。随后 CPU 会将计算好的内容提交到 GPU 去,由 GPU 进行变换、合成、渲染。随后 GPU 会把渲染结果提交到

    2024年01月22日
    浏览(44)
  • Springboot线上环境彻底关闭Swagger-UI

    Springboot线上环境彻底关闭Swagger-UI 1.SwaggerConfig使用@Profile排除线上环境其他环境生效 2.创建一个控制类使用@Profile仅线上环境生效,使访问swagger-ui.html返回404 通过这种方式可以彻底关闭线上环境访问swagger-ui.html直接返回404

    2024年02月16日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包