片頭聲明:
一、本片是據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