BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

Google的Android性能模式

| 作者 Abel Avram 关注 9 他的粉丝 ,译者 臧秀涛 关注 4 他的粉丝 发布于 2015年1月11日. 估计阅读时间: 6 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

Google开发者YouTube频道发布了探讨Android性能模式的16个视频, 列出了开发者在创建应用时容易出现的一些性能问题,同时提供了很多处理建议。本文是对这些问题和建议的总结。

渲染性能101。这一系列视频的讲师是Colt McAnlis,据他介绍,不当的渲染是Android上大部分性能问题的根源。如果一个Activity需要16毫秒以上的时间来准备在屏幕上渲染下一帧,系统将放弃这一帧。应用的用户会感觉滑动不流畅,或者变换有延迟,从而导致体验不好。McAnlis推荐了很多用于检查此类问题的工具:Hierarchy ViewerTraceview、Profile GPU Rendering、Debug GPU Overdraw和GPU View Updates。

建议尽量减少失效(invalidation)和布局(layout)的数量。前者可以用Developer Option Show GPU View Updates可视化地观察,而后者可以使用Hierarchy Viewer来分析。

过度绘制。过度绘制衡量的是一个特定的像素在一帧中被绘制的次数。当然这个值最好是1, 但有时候并不是这样。Debug GPU Overdraw这款工具可以显示重绘最多的区域,所以开发者就知道要优化什么了。

VSYNC。开发者应该注意帧率变化,尤其是当帧率从高于屏幕刷新率突然掉到低于屏幕刷新率时。这会导致动画出现延迟,用户很容易感知到。

Profile GPU Rendering。从Developer Options设置可以访问这个工具,它能够从屏幕上活动的所有Android Activity生成性能图,这些Activity通常包括通知和导航条,再就是活动的应用。一帧的时间在16毫秒以下为宜。性能图会包含所有和渲染相关的主要活动的计时信息,这些活动包括更新显示列表、执行显示列表和处理glSwapBuffers。

60 fps。要让人眼对复杂动画有不错的感受,帧率最少要达到60 fps。保持60 fps的帧率并避免变化很重要。

定制视图。有些过度绘制优化,比如不去绘制完全被遮盖的组件,但是当为了创建定制的视图而覆盖onDraw()方法时,渲染过程可能会缺少这样的优化。为尽量减少过度绘制,建议使用canvas.clipRect()来指定定制绘制的精确区域。此外,应该使用quickReject()来确定某个区域是不是在剪掉的矩形之外,如果没有必要,应该避免浪费时间绘制这个区域。

内存搅动。为大量很快就会被丢弃掉的小型对象重复分配内存,会致使垃圾收集器多次介入,如果这些时间正是在16毫秒的窗口绘制时间内,可能会导致丢帧。借助Android Studio Memory Monitor,开发者可以将垃圾收集活动以可视化方式显示出来,并确定是否有过多的垃圾收集。之后可以利用Allocation Tracker来确定这些内存对象从何而来。然后修复可能导致问题的相关代码,从而避免某些内存分配,或者是把这些分配移到循环之外。此外,对象不应该在onDraw()内分配,因为这个方法1秒会调用很多次。如果应用确实需要大量很快就要丢弃的对象,建议使用对象池,一次创建,多次复用,从而避免垃圾收集。

内存泄漏。内存泄漏使垃圾收集消耗的时间变长,这又会影响帧率。为确保在用户离开某个Android Activity之后,不会出现内存泄漏,McAnlis建议创建一个不需要消耗内存,或者只需要消耗极少内存的空Activity,转到这个空的Activity并强制执行一次垃圾收集。建议在转移之前和之后,使用Android Studio中的堆和分配跟踪工具来确定这个Activity是否有内存泄漏。

电量消耗。根据普渡大学和微软的一篇研究论文(PDF),大约70%的电量是被第三方广告模块消耗的,它们会执行数据分析、位置发现和广告下载等操作。只有30%的电量是应用中实际活动消耗的。Google建议开发者仔细处理电量消耗问题,因为这是用户最关心的。最重要的建议是,除非绝对必要,不要将设备从睡眠中唤醒。如果必须唤醒,建议使用 WakeLock,并设置一个超时时间,以确保如果应用出现问题,设备可以回到睡眠状态。另一个思路是使用AlarmManager.setInexactRepeating() ,将唤醒操作和另一个活动结合起来,从而节省电量。

可以将某些CPU密集型操作推迟到连上充电器并连接到WiFi时,或者将多个工作组合到一次唤醒操作中。这可以借助JobScheduler API,它支持将某些工作延迟一段时间。还有一个建议,要小心地使用网络连接,因为在发送完一个网络请求和接收到一个响应之后,设备要保持至少5秒钟的唤醒状态,以备从服务器传过来的另一个数据包。

McAnlis还建议利用Settings|Battery和Battery Historian 工具提供的电量消耗详情来监控应用随时间变化的耗电情况。

 

查看英文原文:Google’s Android Performance Patterns

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

好文章 by see sai

好文章

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT