常见的手机卡顿现象:
- 视频加载慢;
- 画面卡顿、卡死、黑屏;
- 声音卡顿、音画不同步;
- 动画帧卡顿,交互响应慢;
- 滑动不跟手;
- 列表自动更、滚动不流畅;
- 网络响应慢、数据和画面展示慢;
- 过度动画生硬;
- 界面不可交互、卡死;
这些体验对于用户来说是非常糟糕的,可以说流畅行体验对于用户来说至关重要。
市面上绝大多数的 Android 设备的屏幕刷新率是 60Hz,也就是大概 16ms 刷新一次屏幕,假如花了 24ms 来绘制这一帧,就会出现掉帧的现象,在用户看来就是界面不流畅,卡顿。另外,如果系统准备绘制新的一帧到屏幕上,但是这一帧并没有准备好,就不会有绘制操作,画面也不会刷新。Android 渲染机制
一般而言,GPU 的帧速率应该高于屏幕的刷新频率,才不会卡顿和掉帧。
卡顿的本质原因是错过了展示的时间
- 常规影响:层级以及过度绘制导致;
- 内存影响:STW 现象导致,自定义 View 的绘制,new 对象
- 线程影响:阻塞当前住线程的代码都会造成卡顿
-
UI线程阻塞:UI线程是主线程,很多性能卡顿的问题是由于我们在主线程中做了大量的耗时操作引起的,比如 IO 操作、网络请求、SQL 操作、列表刷新等。
-
将耗时操作放在子线程中,避免阻塞 UI 线程;
-
在 Android 5.0 的版本中,引入了 RenderThread 线程,也就是渲染线程,用于向 GPU 发送实际渲染的操作;
-
-
垃圾回收机制(GC):在 GC 期间会暂停当前所有业务线程,也就是 STW(stop the world)。
-
内存泄漏:未及时释放无用的对象和资源会导致内存泄漏,最终引发内存溢出和应用卡顿。常见的内存泄漏情况包括未关闭的数据库连接、未释放的 Bitmap 对象等。
- 对于持有 Context 的对象,使用弱引用或静态弱引用来避免内存泄漏;
- 确保在不再使用的时候及时释放对象和资源,如关闭数据库连接,释放 Bitmap 对象等;
-
图片加载不当:大图加载、频繁的图片加载和未释放的图片资源会占用大量内存和带宽,导致应用卡顿;
- 使用图片加载库(如 Glide、Picasso)来加载图片,它们可以自动进行图片压缩和内存缓存,减少内存占用和加载时间;
- 对于大图,使用 BitmapFactory.Options 进行图片压缩;
- 及时释放不再使用的图片资源,避免占用过多的内存;
-
数据处理不当:当处理大量数据时,未使用合适的数据结构和算法,或将耗时的数据处理操作放在主线程中,会导致应用卡顿;
- 使用合适的数据结构和算法来处理大量数据,避免耗时的遍历操作
- 将耗时的数据处理操作放在子线程中进行,避免阻塞 UI 线程;
因此,引起卡顿的核心原因:内存和线程。