前言
之前在项目中做过一些Android卡顿以及性能优化的工作,但是一直没时间总结,趁着这段时间把这部分总结一下。
GitHub系统教程学习地址:https://github.com/Timdk857/Android-Architecture-knowledge-2-
包括【面试专题】、【Jetpack】、【Android framework全套学习笔记】、【flutter全套教程】、【微信小程序全套教程】、【全方位性能优化专题】持续更新中~~
欢迎白嫖、标星、指教~~
作者:Hanking
链接:https://juejin.im/post/5eec6dece51d4573d27cee2a
卡顿
在应用开发中如果留意到log的话有时候可能会发下下面的log信息:
I/Choreographer(1200): Skipped 60 frames! The application may be doing too much work on its main thread.
在大部分Android平台的设备上,Android系统是16ms刷新一次,也就是一秒钟60帧。要达到这种刷新速度就要求在ui线程中处理的任务时间必须要小于16ms,如果ui线程中处理时间长,就会导致跳过帧的渲染,也就是导致界面看起来不流畅,卡顿。如果用户点击事件5s中没反应就会导致ANR。
帧率
即 Frame Rate,单位 fps,是指 gpu 生成帧的速率,60fps,Android中更帧率相关的类是SurfaceFlinger。
SurfaceFlinger surfaceflinger作用是接受多个来源的图形显示数据,将他们合成,然后发送到显示设备。比如打开应用,常见的有三层显示,顶部的statusbar底部或者侧面的导航栏以及应用的界面,每个层是单独更新和渲染,这些界面都是有surfaceflinger合成一个刷新到硬件显示。
在显示过程中使用到了bufferqueue,surfaceflinger作为consumer方,比如windowmanager管理的surface作为生产方产生页面,交由surfaceflinger进行合成。
VSync
Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,VSync是Vertical Synchronization(垂直同步)的缩写,是一种在PC上很早就广泛使用的技术,可以简单的把它认为是一种定时中断。而在Android 4.1(JB)中已经开始引入VSync机制,用来同步渲染,让UI和SurfaceFlinger可以按硬件产生的VSync节奏进行工作。
安卓系统中有 2 种 VSync 信号: 1、屏幕产生的硬件 VSync: 硬件 VSync 是一个脉冲信号,起到开关或触发某种操作的作用。 2、由 SurfaceFlinger 将其转成的软件 Vsync 信号:经由 Binder 传递给 Choreographer。
除了Vsync的机制,Android还使用了多级缓冲的手段以优化UI流程度,例如双缓冲(A+B),在显示buffer A的数据时,CPU/GPU就开始在buffer B中准备下一帧数据:但是不能保证每一帧CPU、GPU都运行状态良好,可能由于资源抢占等性能问题导致某一帧GPU掉链子,vsync信号到来时buffer B的数据还没准备好,而此时Display又在显示buffer A的数据,导致后面CPU/GPU没有新的buffer着手准备数据,导致卡顿(jank)。
卡顿原因
从系统层面上看主要以下几个方面的原因会导致卡顿:
1. SurfaceFlinger 主线程耗时
SurfaceFlinger 负责 Surface 的合成 , 一旦 SurfaceFlinger 主线程调用超时 , 就会产生掉帧 . SurfaceFlinger 主线程耗时会也会导致 hwc service 和 crtc 不能及时完成, 也会阻塞应用的 binder 调用, 如 dequeueBuffer \ queueBuffer 等.
2. 后台活动进程太多导致系统繁忙
后台进程活动太多,会导致系统非常繁忙, cpu \ io \ memory 等资源都会被占用, 这时候很容易出现卡顿问题 , 这也是系统这边经常会碰到的问题。 dumpsys cpui