如何从软硬件层面提升 Android 动画性能?
若是有人问如何解决动画性能不佳的问题,Dan Lew Codes 总会反问:你是否使用了硬件层?
动画放映过程中每帧画面可能都要重绘。如果使用视图层,,渲染过的视图可以存入离屏缓存以待将来重用,而无需每帧重绘。
此外,硬件层缓存与 GPU 中,这使得动画放映中的某些操作更加快速。简单的转换(平移,旋转,缩放,开端)可通过硬件层快速渲染。由于许多动画只是这些转换的组合,使用硬件层可大大提高动画性能。
Usage
应用
硬件层 API 十分简单:使用 View.setLayerType()即可。硬件层设定只能暂时使用,因为它们并非没有代价(下文会有更多相关介绍)。基本过程如下:
- 动画过程中,对每个需要缓存的视图调用View.setLayerType(View.LAYER_TYPE_HARDWARE, null)
- 运行动画
- 动画结束时,使用 View.setLayerType(View.LAYER_TYPE_NONE, null)清除缓存。
以下为上述过程的具体实施:
// Set the layer type to hardware
myView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
// Setup the animation
ObjectAnimator animator = ObjectAnimator.ofFloat(myView, View.TRANSLATION_X, 150);
// Add a listener that does cleanup
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animatoranimation){
myView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
// Start the animation
animator.start();
如果你使用 minSdkVersion 16以上版本与ViewPropertyAnimator,可用简便的withLayer()代替上述方法。
myView.animate()
.translationX(150)
.withLayer()
.start();
这样做之后,动画变得很流畅!
警告
…你也知道,事实并非如此简单。
硬件层在提高动画性能方面能力优异。然而,如果使用不当,也可能弊大于利。千万不要盲目使用硬件层!
首先,在很多情况下,硬件层实际进行的操作可能不止于简单的视图渲染。缓存硬件层的耗时不少,因为第一步其实包含两个过程:一、把视图渲染进 GPU 的层中。二、GPU 将该层渲染为视窗。如果该视图渲染比较简单(例如色彩单一),硬件层可能在初始过程中导致非必要的内存开销。
第二,对于所有缓存,都存在缓存失效的可能。在动画过程中,如果有人调用了 View.invalidate(),则硬件层不得不再次渲染。经常这样做事实上比没有硬件层还要糟糕,因为(如前所述)硬件层在初始化缓存时会增加内存开销。如果经常性地二次缓存硬件层,势必影响动画性能!
由于动画经常包括多个移动部件,该问题极易发生。假定你在设置一个具有三个移动部件的动画。
父 ViewGroup
-->子视图1(向左平移)
-->子视图2(向右平移)
-->子视图3(向上平移)
假使你在父ViewGroup 配置了单独的硬件层,会造成缓存持续失效,这是因为ViewGroup(作为整体)由于其子视图的变化而持续改变。然而,每个独立的视图来说,只是在平移而已。因此,最好为每个子视图(而非父容器)配置硬件层。重申一点:为多个视图配置硬件层,可保证其在动画过程中不失效。
“展示硬件层更新”是用于追踪此类问题的好工具。每当视图渲染硬件层时,它会使视图闪现绿色。在动画开始时(即硬件层初始渲染)时它只会闪光一次。然而,如果你的视图在整个动画过程中一直呈现绿色,说明你遇到缓存失效问题了。
第三,硬件层会占用GPU存储空间,你当然不想出现内存泄露。所以,你只应在必要时使用硬件层,比如动画展示过程。
综上所述-并不存在硬性规则。安卓渲染系统是复杂的,经常让我吃惊。对于所有性能问题,检测是关键。“GPU渲染分析”和“硬件层更新展示”设置能用于有效判断硬件层的作用好坏。
举例
我写了一个例子以演示硬件层的基本应用。你可以在此处得到源码。
以下是启用GPU渲染分析设置后,应用在GalaxyNexus(一个又老又慢的设备)上的运行结果

没有硬件层,如此简单的动画也非常糟糕,经常性地位于绿线之上意味着应用性能简直是一团乱麻。相反,使用了硬件层的版本则一直在绿线之下-太棒了!
第三个案例展示了动画中使用硬件层但是缓存失效造成的危害。因为误使硬件层,许多性能提升也毁于一旦。(奇怪之处在于-如果它缓存失效,为什么并不像没有使用硬件层那样慢呢?虽然我也无法完全理解个中缘由,但显然,即使它每一步都要重绘,硬件层还是带来一些有利的优化。不过,最好还是正确地使用硬件层。)
这个故事要的主旨是:硬件层的确有利于提升动画性能,但必须正确使用之。
软件层优化
从硬件层面进行了优化,那么如何从软件层面进行快速定位及优化呢?
使用OneAPM可以快速定位分析UI性能,Mobile Insight的卡顿可以直观地展示这些信息。

可以分析绘制APP卡顿趋势图,精确定位每1秒内的绘图刷新信号中断的次数,从多维度分析卡顿现象,如APP版本、操作系统版本的分布情况等。

卡顿详情列表展示:访问时间,发生卡顿时的流畅度,耗时,发生卡顿时的设备信息,APP版本,操作系统及版本,CPU信息
通过分析该页面信息可以清楚了解到卡顿来源,以便针对性快速优化。

动画卡顿原因
动画卡顿的原因大概有这样三种,这些因素将直接影响动画的性能,导致卡顿。即:
- 手势滑动速度
- 帧率
- 触摸事件响应的速度
手势滑动、帧率是跟各种手机设备有直接的关系,各种各样的硬件设备会表现出不一样的性能,如果从这个方面入手考虑优化,就十分需要 OneAPM Mobile Insight 这样的从多维度来分析性能的一款工具。
原文地址:http://blog.danlew.net/2015/10/20/using-hardware-layers-to-improve-animation-performance/
如何从软硬件层面提升 Android 动画性能?的更多相关文章
- 提升Android ListView性能的几个技巧
ListView如何运作的? ListView是设计应用于对可扩展性和高性能要求的地方.实际上,这就意味着ListView有以下2个要求: 尽可能少的创建View: 只是绘制和布局在屏幕上可见的子Vi ...
- js动画性能提升笔记
JavaScript动画的性能并不亚于CSS动画.因此,如果使用了现代的动画库,例如Velocity,那么动画引擎的性能将不再是app的瓶颈,构成瓶颈的只有代码. 网络性能相关 动画是浏览器运行中资源 ...
- 通过硬件层提高Android动画的性能
曾有许多人问我为什么在他们开发的应用中,动画的性能表现都很差.对于这类问题,我往往会问他们:你们有尝试过在硬件层解决动画的性能问题么? 我们都知道,在播放动画的过程中View在每一帧动画的显示时重绘自 ...
- 盒子端 CSS 动画性能提升研究
不同于传统的 PC Web 或者是移动 WEB,在腾讯视频客厅盒子端,接大屏显示器(电视)下,许多能流畅运行于 PC 端.移动端的 Web 动画,受限于硬件水平,在盒子端的表现的往往不尽如人意. 基于 ...
- 3D硬件加速提升动画性能 与 z-index属性
目录 1. chrome Layer borders 2. 层创建标准 3. 例子 总结 1. chrome Layer borders <WebKit技术内幕>第二章介绍了网页的结构,其 ...
- 使用CSS3开启GPU硬件加速提升网站动画渲染性能
遇到的问题: 网站本身设计初衷就没有打算支持IE8及以下版本浏览器,并不是因为代码兼容性问题,而是真的不想迁就那些懒得更新自己操作系统和浏览器的用户,毕竟是我自己的网站,所以我说了算!哈哈~ 没有了低 ...
- Android界面性能调优手册
界面是 Android 应用中直接影响用户体验最关键的部分.如果代码实现得不好,界面容易发生卡顿且导致应用占用大量内存. 我司这类做 ROM 的公司更不一样,预装的应用一定要非常流畅,这样给客户或用户 ...
- android app性能优化大汇总(google官方Android性能优化典范 - 第2季)
Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的 ...
- Android应用性能优化(转)
人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然连贯(帧率为24fps),用手机当然也需要感知屏幕操作的连贯性(尤其是动画过度),所以Android索性就把达到这 ...
随机推荐
- Yii2查询语句使用不等于号
Yii2 Active Record查询条件使用不等于号,需要使用到 operator format: [operator, operand1, operand2, ...] 运算符格式: [运算符, ...
- 议:如何将树形菜单形式的数据转化成HTML的二维表(相同内容需合并单元格)
一般做OA类管理系统,经常涉及到“组织架构”的概念,那么像这种有上下层级关系的数据一般会做成树形菜单的方式显示,底层代码必定会用到递归算法.这篇随笔的目的就是要谈谈除了用树形菜单来显示这种上下层级关系 ...
- C#学习笔记4:关键词大小写、复合格式化等
1.取消选择的单选按钮值 RadioButton1.Checked=RadioButton2.Checked = false;//RadioButton1.Text = RadioButto ...
- SQL Server 错误检测与修复
简介 在一个理想的世界中,不会存在任何数据库的损坏,就像我们不会将一些严重意外情况列入我们生活中的日常一样,而一旦这类事情发生,一定会对我们的生活造成非常显著的影响,在SQL Server中也同样如此 ...
- [LaTex]Visio文件转EPS文件[转]
在LaTeX系统中,由于DVI 文件经常被转为PostScript 文件,所以LATEX 支持最好的是EPS 格式(Encapsulated Post-Script ,是PostScript 语言的子 ...
- Android Metro风格的Launcher开发系列第一篇
前言:从毕业到现在已经三年多了,回忆一下这三年基本上没有写过博客,总是觉得忙,没时间写,也觉得写博客没什么大用.但是看到很多大牛们都在写博客,分享自己的东西,所以嘛本着向大牛看齐,分享第一,记录第二的 ...
- 12天学好C语言——记录我的C语言学习之路(Day 3)
12天学好C语言--记录我的C语言学习之路 Day 3: 不知不觉到了第三天的学习,我们前两天学习的东西很杂乱,各个方面都有学习.我觉得这不是不系统,也不是学的不扎实,这种学习对于初学者而言我认为是很 ...
- C#构造函数相关主题
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- mysql空间数据相关操作
建表语句: CREATE TABLE ts.points ( name ) NOT NULL, location POINT NOT NULL, description ) ); 添加记录如下: IN ...
- 懒人记录 Hadoop2.7.1 集群搭建过程
懒人记录 Hadoop2.7.1 集群搭建过程 2016-07-02 13:15:45 总结 除了配置hosts ,和免密码互连之外,先在一台机器上装好所有东西 配置好之后,拷贝虚拟机,配置hosts ...