Android 优化之卡顿优化的实现

Android 系统每隔 16ms 会发出 VSYNC 信号重绘界面(Activity)。之所以是 16ms,是因为 Android 设定的刷新率是 60FPS(Frame Per Second),也就是每秒 60 帧的刷新率,约合 16ms 刷新一次。

这就意味着,我们需要在 16ms 内完成下一次要刷新的界面的相关运算,以便界面刷新更新。

假设我们更新屏幕的背景图片需要 24ms 来做这次运算,当系统在第一个 16ms 时刷新界面,由于运算还没有结束,无法绘出图片。当系统隔 16ms 再发一次 VSYNC 信息重绘界面时,用户才会看到更新后的图片。也就是说 32ms 后才看到了这次刷新(并不是 24ms),这就是丢帧(dropped frame)。

丢帧给用户的感觉就是卡顿,而且如果运算过于复杂,丢帧会更多,导致界面常常处于停滞状态。

卡顿原因

过于复杂的布局

  • 界面性能取决于 UI 的渲染性能,UI 渲染的整个过程由 CPU 和 GPU 两个部分协同完成。CPU 负责 UI 布局元素的 Measure、Layout、Draw 等相关运算执行,GPU负责栅格化(rasterization),将 UI 元素绘制到屏幕上。
  • 如果 UI 布局层次太深,或是自定义控件的 onDraw 中有复杂运算,CPU 的相关运算就可能大于 16ms,导致卡顿。

过度绘制

UI 线程的复杂运算

  • UI 线程的复杂运算会造成 UI 无响应,导致 ANR,但更多的是造成 UI 响应停滞卡顿,ANR 是卡顿的极致。

频繁的 GC

优化方法

1、减少刷新次数

比如进度更新,要进度有变化再去刷新,且保证频率不得高于系统的刷新频率。

2、避免非必要的刷新

若控件不可见,则无需刷新。

3、避免后台线程影响

如列表控件,在滑动时不要去加载图片,可以在滑动监听里停止图片的加载。

4、局部刷新

如 RecyclerView 的 DiffUtil。自定义 View 可以使用下面两个方法:

invalidate(Rect dirty);
invalidate(int left, int top, int right, int bottom);

5、尽量使用属性动画,它减少了自身的重绘。最后要清除

StringBuilder,List 等在创建时传入一个合适的参数指定初始容量,以避免频繁扩容的开销。

6、开启硬件加速

7、原理可见 Android硬件加速原理与实现简介,理解Android硬件加速原理的小白文

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 中要处理中文长文本,需要关闭硬件加速。因为每个中文编码不一样,缓存效果不理想。

监控

  1. 《Android 应用性能优化最佳实践》2.8 章,主要利用 MainLooper 里的 Printer。
  2. BlockCanary 开源库
  3. StrctMode

ANR

Activity 的 View:5 秒无响应
BroadcastReceiver:10 秒无响应
Service:20 秒无响应

ANR 时,系统会生成一个 traces.txt 的文件放在 /data/anr/ 下。通过 adb 命令将其导出到本地

$adb pull data/anr/traces.txt ~/Desktop

UI 线程做耗时操作,内存泄露导致内存不足都可能产生 ANR。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • android 之listview 优化方法

    这个东西做android是必备的,我相信你一定也会,但是我写下来的目的就是记录一下. 这个东西面试也很多会问到的,那么我们怎么回答那? 首先我认为有这么几点: 1.listview在定义的时候宽和高最好固定一下,这样可以减少listview测量次数,避免每次加载的时候都要去进行测量. 2.分页加载,这也是优化之一,优化内存,还有体验感,有兴趣的可以试试大数据加载: 3.convertView 就是布局的复用: 4.ViewHolder的使用 目的减少findviewByID的次数: 下面代码验证

  • Android 优化之app启动优化的实现

    App 启动方式 冷启动 App 没有启动过或 App 进程被杀,系统中不存在该 App 进程,此时启动即为冷启动.需要创建 App 进程,加载相关资源,启动 Main Thread,初始化首屏 Activity 等.在这个过程中,屏幕会显示一个空白的窗口(颜色基于主题),直至首屏 Activity 完全启动. 热启动 热启动意味着 App 进程只是处于后台,系统只是将其从后台带到前台展示给用户.类同与冷启动,在这个过程中,屏幕会显示一个空白的窗口(颜色基于主题),直至 activity 渲染完

  • Android端TCP长连接的性能优化教程分享

    前言 大家应该都知道,在Android端实现TCP长连接场景其实不多,我们最熟悉的不过推送和HTTP协议的实现(OkHttp),本文讨论的是在实现推送长连接的情况下怎么来做性能优化,下文只是我的一点拙见,有不妥之处还望指出,下面话不多说了,来一起看看详细的介绍吧. 推送长连接 可以说大部分APP是离不开推送(push)这个功能的,不过平常我们都是接入第三方SDK(极光.个推等)居多,因为要做一个推送服务,不光客户端要编写相应的Socket通信代码,服务器端更是麻烦,要处理大规模的长连接服务,消息

  • 详解Android布局优化

    怎样才能写出优秀的Android App,是每一个程序员追求的目标.那么怎么才能写出一个优秀的App呢?相信很多初学者也会有这种迷茫.一句话来回答这个问题:细节很重要.今天我们就从最基础的XML布局来谈谈怎么提高Android性能问题吧! 也许你经常会遇到比较复杂的布局,这种情况下,最简单的方法就是多层嵌套实现效果,但是最简单的方法是否是最优的方法呢? 这里需要打一个大大的问号?????经验告诉我们,往往简单的方法,得到的结果不是最优解,那么我们通过一个例子来研究一下怎么去优化我们的XML布局吧

  • Android实战APP启动速度优化

    APP启动速度非常重要,APP启动速度慢,可能会造成用户体验不良好,尤其是在最近用Android studio之后,如果长时间不打开app,启动速度就会特别的慢,下面我们一起探讨一下影响app启动速度的原因,以及解决方案. 检测启动时间 首先我们要知道app的启动时间,然后你也可以凭着感觉来,这里我教大家一个装逼的方法: adb shell am start -W [packageName]/[.MainActivity] 用adb命令可以检测启动时间,示例如下: ./adb shell am

  • Android图片性能优化详解

    1. 图片的格式 目前移动端Android平台原生支持的图片格式主要有:JPEG.PNG.GIF.BMP.和WebP(自从Android 4.0开始支持),但是在Android应用开发中能够使用的编解码格式只有三种:JPEG.PNG.WebP,图片格式可以通过查看Bitmap类的CompressFormat枚举值来确定. public static enum CompressFormat { JPEG. PNG. WebP; private CompressFormat() { } } 如果要在

  • Android优化之电量优化的实现

    Android 5.0 后用 Battery Historian 工具分析电量. 耗电因素 移动网络请求 手机通过内置的射频模块和基站联系,从而链接上网的,而这个射频模块(radio)是非常耗电的,为了控制这个射频模块的耗电,硬件驱动及 Android RIL 层做了很多处理.例如可以单独关闭 radio(飞行模式),间歇性假休眠 radio(有数据发生时才上电,保持一个频率的与基站交互)等等.如今的 App 都是移动互联网 App,不可避免的会有大量的网络请求,会导致 radio 一直处于活跃

  • Android 优化之卡顿优化的实现

    Android 系统每隔 16ms 会发出 VSYNC 信号重绘界面(Activity).之所以是 16ms,是因为 Android 设定的刷新率是 60FPS(Frame Per Second),也就是每秒 60 帧的刷新率,约合 16ms 刷新一次. 这就意味着,我们需要在 16ms 内完成下一次要刷新的界面的相关运算,以便界面刷新更新. 假设我们更新屏幕的背景图片需要 24ms 来做这次运算,当系统在第一个 16ms 时刷新界面,由于运算还没有结束,无法绘出图片.当系统隔 16ms 再发一

  • Android中卡顿优化布局详细介绍

    目录 背景 实践过程 如何渲染界面 什么是过度绘制 如何查看绘制维度 界面优化 硬件加速原理 总结 背景 在当下移动互联网后半场,手机已经是人手必备的设备.App是离用户最近的应用,界面又是最直观影响用户体验的关键部分,其流畅度直接影响用户对产品的评价和留存. 技术是服务于人的,如果技术无法给你带来良好的体验,那技术本身的存在就具有争议. 所以界面性能是至关重要的,不可忽视. 实践过程 布局代码是最基础的,但也是最重要的. 首先我们看个简单小案例 不同深浅的颜色来表示过度绘制: 没颜色:没有过度

  • Android Bitmap的加载优化与Cache相关介绍

    一 . 高效加载 Bitmap BitMapFactory 提供了四类方法: decodeFile,decodeResource,decodeStream 和 decodeByteArray 分别用于从文件系统,资源,输入流以及字节数组中加载出一个 Bitmap 对象. 高效加载 Bitmap 很简单,即采用 BitMapFactory.options 来加载所需要尺寸图片.BitMapFactory.options 就可以按照一定的采样率来加载缩小后的图片,将缩小后的图片置于 ImageVie

  • Android性能优化之弱网优化详解

    目录 弱网优化 1.Serializable原理 1.1 分析过程 1.2 Serializable接口 1.3 ObjectOutputStream 1.4 序列化后二进制文件的一点解读 1.5 常见的集合类的序列化问题 1.5.1 HashMap 1.5.2 ArrayList 2.Parcelable 2.1 Parcel的简介 2.2 Parcelable的三大过程介绍(序列化.反序列化.描述) 2.2.1 描述 2.2.2 序列化 2.2.3 反序列化 2.3 Parcelable的实

  • Android性能优化系列篇UI优化

    目录 前言 一.UI优化 1.1 系统做的优化 1.1.1 硬件加速 1.2 优化方案 1.2.1 java代码布局 1.2.2 View重用 1.2.3 异步创建view 1.2.4 xml布局优化 1.2.5 异步布局框架Litho 1.2.6 屏幕适配 1.2.7 Flutter 1.2.8 Jetpack Compose 1.3 工具篇 1.3.1 Choreographer 1.3.2 LayoutInspector/Android Device Monitor 1.3.3 Systr

  • Android使用ViewPager快速切换Fragment时卡顿的优化方案

    当ViewPager切换到当前的Fragment时,Fragment会加载布局并显示内容,如果用户这时快速切换ViewPager,即Fragment需要加载UI内容,而又频繁地切换Fragment,就容易产生卡顿现象(类似在ListView快速滑动的同时加载图片容易卡顿). 优化方案: 1.Fragment轻量化 如果ViewPager加载的Fragment都比较轻量,适当精简Fragment的布局,可提高Fragment加载的速度,从而减缓卡顿现象. 2.防止Fragment被销毁 ViewP

  • CSS3 动画卡顿性能优化的完美解决方案

    为什么会卡顿? 有一个前提必须要提,前端开发者们都知道,浏览器是单线程运行的.但是我们要明确以下几个概念:单线程,主线程和合成线程. 虽然说浏览器执行js是单线程执行(注意,是执行,并不是说浏览器只有1个线程,而是运行时,runing),但实际上浏览器的2个重要的执行线程,这 2 个线程协同工作来渲染一个网页:主线程和合成线程. 一般情况下,主线程负责:运行 JavaScript:计算 HTML 元素的 CSS 样式:页面的布局:将元素绘制到一个或多个位图中:将这些位图交给合成线程. 相应地,合

  • Android高级开发之性能优化典范

    本章介绍android高级开发中,对于性能方面的处理.主要包括电量,视图,内存三个性能方面的知识点. 1.视图性能 (1)Overdraw简介 Overdraw就是过度绘制,是指在一帧的时间内(16.67ms)像素被绘制了多次,理论上一个像素每次只绘制一次是最优的,但是由于重叠的布 局导致一些像素会被多次绘制,而每次绘制都会对应到CPU的一组绘图命令和GPU的一些操作,当这个操作耗时超过16.67ms时,就会出现掉帧现象,表现为应用卡顿,所以对重叠不可见元素的重复绘制会产生额外的开销,需要尽量减

  • 解决android studio卡顿,提升studio运行速度的方法

    mac版本: 点击Finder,在应用程序中找到android studio----->Contents文件夹----->bin文件夹----->studio.vmoptions文件. 如图 以文本形式打开studio.vmoptions文件,会看到如下图 将前三个值改大一些,保存并退出文件,重启android studio即可. window版本: 找到android studio安装路径----->bin文件夹----->studio.exe.vmoptions,打开并修

  • Android教你如何发现APP卡顿的实现

    最近部门打算优化下 APP 在低端机上的卡顿情况,既然想优化,就必须获取卡顿情况,那么如何获取卡顿情况就是本文目的. 一般主线程过多的 UI 绘制.大量的 IO 操作或是大量的计算操作占用 CPU,导致 App 界面卡顿.只要我们能在发生卡顿的时候,捕捉到主线程的堆栈信息和系统的资源使用信息,即可准确分析卡顿发生在什么函数,资源占用情况如何.那么问题就是如何有效检测 Android 主线程的卡顿发生? 用 adb 系统工具观察 App 的卡顿数据情况,试图重现场景来定位问题. 常用的方式是使用

随机推荐