造成android UI卡顿的原因及解决方法
Android 系统每隔 16ms 会发出 VSYNC 信号重绘界面(Activity)。之所以是 16ms,是因为 Android 设定的刷新率是 60FPS(Frame Per Second),也就是每秒 60 帧的刷新率,约合 16ms 刷新一次。如果UI线程的执行时间超过16ms,则会产生丢帧的现象,而大量的丢帧就会造成卡顿,影响用户体验。
文章开始前小编这里有一份Android App性能优化学习手册,主要内容有App启动优化、UI优化、卡顿优化等知识点详解,感兴趣的朋友私信小编领取。下面小编就带大家了解造成这个现象的原因有以及解决方法。
造成UI卡顿的原因
造成卡顿的原因多种多样,小到代码的编写和使用的数据结构不合理,大到系统资源不能及时分配,所以我们这里主要是介绍常见的会引起卡顿的原因,主要分为以下个方面:
过于复杂的布局
-
界面性能取决于 UI 的渲染性能,UI 渲染的整个过程由 CPU 和 GPU 两个部分协同完成。CPU 负责 UI 布局元素的 Measure、Layout、Draw 等相关运算执行,GPU负责栅格化(rasterization),将 UI 元素绘制到屏幕上。
-
如果 UI 布局层次太深,或是自定义控件的 onDraw 中有复杂运算,CPU 的相关运算就可能大于 16ms,导致卡顿。
过度绘制
UI 线程的复杂运算
- UI 线程的复杂运算会造成 UI 无响应,导致 ANR,但更多的是造成 UI 响应停滞卡顿,ANR 是卡顿的极致。
频繁的 GC
上面这些导致卡顿的原因都是我们平时开发中非常常见的。有些人可能会觉得自己的应用用着还蛮OK的,其实那是因为你没进行一些瞬时测试和压力测试,一旦在这种环境下运行你的App你就会发现很多性能问题。
优化方法
1、减少刷新次数
比如进度更新,要进度有变化再去刷新,且保证频率不得高于系统的刷新频率。
2、避免非必要的刷新
若控件不可见,则无需刷新。
3、避免后台线程影响
如列表控件,在滑动时不要去加载图片,可以在滑动监听里停止图片的加载。
4、局部刷新
如 RecyclerView 的 DiffUtil。自定义 View 可以使用下面两个方法:
invalidate(Rect dirty);
invalidate(int left, int top, int right, int bottom);
5、尽量使用属性动画,它减少了自身的重绘。最后要清除
StringBuilder,List 等在创建时传入一个合适的参数指定初始容量,以避免频繁扩容的开销。
6、开启硬件加速
Application 级别
<application android:hardwareAccelerated="true" />
Activity 级别
<activity android:hardwareAccelerated="true" />
Window 级别
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
View 级别
// 如果是 software,会将 View 绘制到一个 Bitmap,
// 然后依然是通过硬件加速将 Bitmap 绘制到 Canvas
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-
LAYER_TYPE_NONE:普通渲染方式,不会返回一个离屏的缓冲,默认值。
-
LAYER_TYPE_HARDWARE:如果这个应用使用了硬件加速,这个 View 将会在硬件中渲染为 硬件纹理,如果应用程序并没有被硬件加速,则其效果和 LAYER_TYPE_SOFTWARE 相同。
-
LAYER_TYPE_SOFTWARE:此 View 通过软件渲染为一个 Bitmap。
检查是否开启了硬件加速
view.isHardware-Accelerated();
Canvas.isHardwareAccelerated();
如果 View 中要处理中文长文本,需要关闭硬件加速。因为每个中文编码不一样,缓存效果不理想。
监控
-
《Android 应用性能优化最佳实践》2.8 章,主要利用 MainLooper 里的 Printer。
-
BlockCanary 开源库
-
StrctMode
ANR
Activity 的 View:5 秒无响应 BroadcastReceiver:10 秒无响应 Service:20 秒无响应
ANR 时,系统会生成一个 traces.txt 的文件放在 /data/anr/ 下。通过 adb 命令将其导出到本地
$adb pull data/anr/traces.txt ~/Desktop
UI 线程做耗时操作,内存泄露导致内存不足都可能产生 ANR。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小编。另外,小编为大家准备了一份App性能优化手册,主要内容有App启动优化、UI优化、卡顿优化等知识点详解,感兴趣的朋友可私信小编领取。