大厂面试必备,Android性能优化-检测App卡顿,安卓面试2024

答:为了保证应用的平滑性,每一帧渲染时间不能超过16ms,达到60帧每秒;如果UI渲染慢的话,就会发生丢帧,这样用户就会感觉到不连贯性,我们称之为Jank(APP卡顿);VSync信号由SurfaceFlinger实现并定时发送(每16ms发送),Choreographer.FrameDisplayEventReceiver收到信号后,调用onVsync方法组织消息发送到主线程处理。Choreographer主要功能是当收到VSync信号时,去调用使用通过postCallBack设置的回调函数,在postCallBack调用doFrame,在doFrame中渲染下一帧;FrameDisplayEventReceiver相关代码如下:

Choreographer.java

/**

  • FrameDisplayEventReceiver继承自DisplayEventReceiver接收底层的VSync信号开始处理UI过程。

  • VSync信号由SurfaceFlinger实现并定时发送。FrameDisplayEventReceiver收到信号后,

  • 调用onVsync方法组织消息发送到主线程处理。这个消息主要内容就是run方法里面的doFrame了,

  • 这里mTimestampNanos是信号到来的时间参数。

*/

private final class FrameDisplayEventReceiver extends DisplayEventReceiver

implements Runnable {

private boolean mHavePendingVsync;

private long mTimestampNanos;

private int mFrame;

public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {

super(looper, vsyncSource);

}

@Override

public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {

mTimestampNanos = timestampNanos;

mFrame = frame;

// 发送Runnable(callback参数即当前对象FrameDisplayEventReceiver)到FrameHandler,请求执行doFrame

Message msg = Message.obtain(mHandler, this);

msg.setAsynchronous(true);

// 此处mHandler为FrameHandler,该Handler对应的Looper是主线程的Looper

mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);

}

@Override

public void run() {

mHavePendingVsync = false;

doFrame(mTimestampNanos, mFrame);

}

}

在mHandler.sendMessageAtTime发送消息之后,最终会在主线程的Looper.loop()方法中调用msg.target.dispatchMessage(msg);Looper.loop相关代码可以参考在本文上边进行查看;然后在Handler.dispatchMeassange分发消息,如下所示:

Handler.java

public void dispatchMessage(Message msg) {

// Message的callback实际上就是Handler的post方法所传递的Runnable参数

// 这里首先检查是否有由Runnable封装的消息,如果有,首先处理;

if (msg.callback != null) {

handleCallback(msg);

} else {

// 其次处理mCallback

if (mCallback != null) {

// 如果mCallback的handleMessage方法返回true,那么handler中的handleMessage方法是不会被执行的

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

private static void handleCallback(Message message) {

//在此执行FrameDisplayEventReceiver中的run方法,最终执行doFrame渲染下一帧;

message.callback.run();

}

通过以上流程可以发现,Android渲染每一帧都是通过消息机制来实现的,最终都会在主线Looper.loop()方法中开始渲染下一帧,因为Looper.loop方法在进行消息分发时是串行执行的,这样如果上一个消息分发时间过长即msg.target.dispatchMessage(msg)执行时间过长,就会导致在VSYNC到来时进行下一帧渲染延迟执行,就不能保证该帧在16ms内完成渲染,从而导致丢帧;所以主线程Looper.loop方法中msg.target.dispatchMessage(msg)执行时间过长就会导致APP卡顿;因此通过检测msg.target.dispatchMessage(msg)执行时间就可以检测APP卡顿;

Android消息机制的重要性

1.在卡顿监测会用到消息机制;主要是发送一个延时消息来监测是否,在执行时间内没有remove该消息就代码APP发生卡顿;

2.ANR监测也是通过发送一个延时消息来监测是否发生ANR;ANR是APP卡顿的极端情况;

3.View监测事件是否长按也用到消息机制,在发生Down的时候会发送一个延时消息,在Up的时候会将该消息Remove掉,如果指定的时间没有发生UP就会触发长按事件;

4.Choreographer在渲染每一帧的时候也是通过发送一个消息,然后在Looper.loop中处理下一个消息时才会去渲染下一帧;

5.Activity生命周期的控制也是在ActivityThread发送不同的消息来切换Activity生命周期;

6.消息机制可以将一个任务切换到其它指定的线程,如AsyncTask;

以上这些场景都用到Android消息机制,还有很多其他未知的场景可能也会用到Android消息机制,所以消息机制在Android中具有很重要的地位;

参考资料

鸿洋:Android UI性能优化 检测应用中的UI卡顿

BlockCanary GitHub地址

Blog in Chinese: BlockCanary.

blockcanary源码学习随笔

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

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

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

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

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

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

推荐学习资料

  • Android进阶学习全套手册

  • Android对标阿里P7学习视频

  • BAT TMD大厂Android高频面试题

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

65ecb71ac0)

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值