片头声明:
一、本片是据Romain Guy剧本编写Android Performance Case Study衍生的电影,某些部分可能因为我的英语水平有限及理解缘由,可能有别于原做者的原意。若有发现,请指正。以利于咱们共同窗习,共同进步。
html
二、本片是继Android性能优化案例研究(上) by孙立出的下版。狗尾续貂,望你们海涵。
剧情介绍:孙立翻译的上半部分是如何发现性能问题,我这的下半部分是如何使用工具肯定这些问题并给与了部分问题的解决方案。对于上部,就再也不这里转载了,能够直接点击上面连接进行阅读学习。也可能过几天会转载过来 android
各位看官,下面就接上部开播:
移除无用的图层:为了减小重绘,咱们首先必须知道,什么会致使重绘。这也是Hierarchy Viewer和Tracer for OpenGl以前的用处所在。
Hierarchy Viewer(图层查看器)是ADT的一部分,能够用于检查View Hierarchy(视图层级)的快照。它在解除布局问题时尤为有用,但也能够方便的检查工做性能。
【重要:默认状况下Hierarchy Viewer只能工做在非安全模式的设备上,好比工程机、平板或者虚拟机。要在全部手机上使用Hierarchy Viewer,须要添加一个叫ViewServer的开源库项目到你的应用中。
https://github.com/romainguy/ViewServer】
在ADT(或者监视器)中打开Hierarchy Viewer视图,而后选择Windows tab。(粗体高亮现实的窗口就是手持终端的foreground设备,通常也就是你要检测的那个界面)。点击高亮显示的条目,而后点击在工具栏中的Load按钮。(它看起来想一个蓝色方块树。)而后耐心等待载入整个树。当这该视图树载入完毕,你将看到以下图类似的画面。【译者:最好使用Monitor,译者屡次使用ADT老是出错。】
如今,View Hierarchy已经在工具中载入成功,咱们能够将其做为一个图片文档导出。只要点击工具栏中的第二个按钮(工具提示为:Capture the window layers捕获窗口图层)。Adobe Photoshop不是必须的软件,可使用与其兼容的工具,好比Pixelmator,GIMP等等。能够下载我生成的PSD文件:
这个图像文件展现了应用中在一个Layer(图层)的每个View。每个layer(图层)基View.getVisibility返回的数据,分别被标记为可见或者不可见的。每个layer(图层)使用View 可用android:id或者它的类名来命名。我开始添加支持组件来重建视图树,我应该完成这个功能。
经过检查这一系列图层,咱们能够快速认出至少一个资源的overdraw,多个全屏背景。第一个就是这第一个layer。称为DecorView。这个视图被Android生成并包含了在主题中的特殊背景。在应用中这个默认梯度(默认透明度)是不可见的。所以能够安全的将其移除。
滚动DecorView你能够看见一个LinearLayout包含了另一个全屏梯度(透明)背景。它与DecorView的背景是彻底同样的,所以,它也是不须要的。惟一可见背景必须保持,它就是命名为id/tweet_list_container的视图。
【移除窗口背景:定义在你主题中的背景 被系统用来在启动的你应用以前做为预显示窗口。千万不要将其设置为null除非你的应用是透明的,相反,应该设置一个你认为好的颜色或者图片,或者在onCreater()方法中调用getWindow().setBackgroundDrawable(null)来将其去掉】。 git
进一步的减小overdraw:
经过图像文件,咱们能够很容易明白应用是怎么生成的。可是它对于移除小区域的overdraw就显得十分吃力。那咱们就须要打开Tracer for OpenGL。在ADT或者Monitor中名字为Tracer for OpenGL的视图,在工具栏中点击箭头那个图标。输入你应用的包名和主Activity的名字,而后选择存放位置(destination File)点击trace按钮。
【建议:OpenGL检测可能很大而且能够真正减速获取图像。 为了让它更小,获取图像更快,不要复选Data Collection Options boxes框。】
github
【Activity名字:当你打开应用后,logcat将显示包名和Activity名字。根据这个你就能够晓得在Tracer for OpenGL中要输入什么东东了。】
当应用已经打开并运行,使可用前两个选项:
* Collection Framebuffer contents on eglSwapBuffers()
* Collection Framebuffer contents on glDraw*()
第一个选项对于快速找到你感兴趣的frame十分有用,然而第二个选项则容许咱们经过绘制命令查看每一个frame生成使用的命令。第二个选项是解决overdraw 问题的关键所在。
开启这两个选项以后,我开始滑动主界面的时间轴。它将花费至关长的时间来获取每个frame(不出意外的话,须要30秒)。所以我建议你下载我获取的文件(http://goo.gl/yPjB5)。你能够在Tracer for OpenGL中点击第一个按钮打开这个文件。
加载完毕后,视图展现你每个发送到GPU的GL命令为一个frame快照。若是你下载个人文件。跳到21Frame处。当一个frame被选中以后,你能够在Frame Sunmmary tab 页中查看它是什么样子的。另外,你能够点击绘制命令,将其蓝色高亮,在Details tab页中查看这个frame的当前状态。
【总结:GL 命令被经过View分组。他们从新建立你在HierarchyViewer或者xml Layout文件夹能够看到的树。这使它很容易就能理解什么View产生了一个什么样的特定操做。】
经过连续点击前三个绘制命令,你能够看出已经在Photoshop中肯定的问题,一个全屏的背景被绘制了三次。
咱们经过查看下载的Tracer,能够发现更多能够优化的地方。当一个tweet(listitem)被绘制,一个ImageView被用于绘制头像(原文是:avatar)。ImageView第一次绘制了一个背景而后绘制头像(avatar)自身。
若是你仔细看,你将会发现背景只是做为图片的一个边界。这意味着,这意味着在头像图片中间的这黑色部分被
overdraw了。这片9path已经被头像图片(avatar)彻底覆盖了。
web
一个对于这个问题的简单修复办法是使这中间可拉伸的9-patch图片透明。Android的2d渲染器优化9patches的透明部分。这个简单的改变将会移除一小部分的overdraw。
有趣的是,一样的问题也出如今了内联媒体(inline media)中。头像图片(Avatars)图片十分小,因此他们overdraw不会致使大的消耗。可是内嵌媒体(inline media)可占据屏幕至关大的一部分区域。问题的修复与上面的方法一致。
【深度优化:我更但愿Android的2d渲染管道有能力自动正确的为你overdraw。咱们已经有了些想法,可是我还不能作出任何关于这方面的承诺。正像加入GPU优化,这只能做用于不透明的元素。】
扁平化视图( 正则表达式
我已经展现了多种你能够用于优化你的应用的工具。我已经花费了大量的时间来描述在这些工具的帮助下,使用什么技术去解决已辨别的问题。可是这个文章将会转到一本书中。检出文档这官方文档( Android developers web site)引用和全部GoogleI/O Android talks.
---Romain Guy 安全
【后语:最好使用Monitor,鄙人在使用ADT的时候老出错。 性能优化
补Traceview操做图:
session
】 app