前言
卡顿场景可分为以下四类:
- UI绘制:绘制、刷新
- 应用启动:安装启动、冷启动、热启动
- 页面跳转:页面间切换、前后台切换
- 事件响应:按键、系统事件、滑动
这四种卡顿场景的根本原因又可以分为两大类:
- 界面绘制:主要原因是绘制的层级深、页面复杂、刷新不合理。
- 数据处理:导致这种卡顿场景的原因是数据处理量太大,一般分为三种情况:
- 一是数据处理在UI线程(这种应该避免)。
- 二是数据处理占用CPU高,导致主线程拿不到时间片。
- 三是内存增加导致GC频繁,从而引起卡顿。
Android系统显示原理
Android的显示过程可以简单概括为:Android应用程序把经过测量、布局、绘制后的surface缓存数据,通过SurfaceFlinger把数据渲染到屏幕上,通过Android的刷新机制来刷新数据。
绘制原理
应用层
在Android的每个view绘制中又三个核心步骤:Mesasure、Layout、Draw。通过Measure和Layout来确定当前需要绘制的view所在的大小和位置,通过绘制(Draw)到surface。
Measure和Layout都是递归来获取view的大小和位置,并且以深度作为优先级,因此层级越深,元素越多,耗时也就越长。
系统层
应用层和系统层是两个不同进程,在Android的显示系统,使用匿名共享内存:SharedClient,每个应用和SurfaceFlinger之间都会创建一个SharedClient。在每个SharedClient中,最多可以创建31个ShardBufferStack,每个Surface都对应一个ShardBufferStack,也就是一个window。 一个SharedClient对应一个Android应用程序,意味着一个Android应用程序最多可以包含31个窗口。
显示整体流程分为三个模块:应用层绘制到缓存区,SurfaceFlinger把缓存区数据渲染到屏幕,由于是两个不同的进程,所以使用Android的匿名共享内存SharedClient缓存需要显示的数据来达到目的。
知道绘制原理后,那么绘制一个单元多长时间才是合理的?
——在理想情况下,60FPS(Frames Per Second 每秒传递的帧数)就感觉不到卡,这意味着每个绘制时长应该在16ms以内。
Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染。若每次都成功就能达到流畅画面的60FPS。若某个操作耗时较久,系统在得到VSYNC信号时就无法正常渲染,这样就会发生丢帧现象。
==卡顿的根本原因==
影响绘制的根本原因有以下两方面:
- ==绘制任务太重==,绘制一帧内容耗时太长。
- ==主线程太忙==,导致VSync信号来时还没有准备好数据导致丢帧。
性能分析工具
性能问题不容易复现,在分析性能问题时需要借助相应的调试工具,比如查看Layout层次的Hierarchy View、Android系统自带的 Profile GPU卡顿检测工具和静态代码检查工具Lint,以及性能分析常用的TraceView和SysTrace等。
卡顿检测工具
Profile GPU Rendering是Android4.1系统开始提供的开发辅助工具,可在开发者选项中打开(华为手机是:GPU呈现模式分析按钮)
特点:
- 是一个图形检测工具,实时反应当前绘制的耗时。
-
提供一个标准耗时,高于标准耗时,表示当前一帧丢失。
image.png<