#翻譯# Android Performance Case Study by Romain...

片頭聲明:
一、本片是據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優化,這隻能做用於不透明的元素。】

扁平化視圖( 正則表達式

Flattening the view hierarchy):


好的,如今咱們已經對overdraw(大部分都是)關心過了,如今讓咱們回過頭來再看看Hierarchy viewer。經過檢查圖 像樹,咱們能試圖肯定不須要的Views。移除Views特別是ViewGroup,這不只能夠提升幀速率,並且還能夠減小內存消耗 ,啓動時間等等。
快速查看Falcon Pro視圖層級,你能夠肯定有幾個ViewGroup和一個單獨的子視圖。這些ViewGroup通常都是不須要而且 很容易移除掉。下面展現的圖片中至少最後面的兩個節點是能夠移除的。

也有一些另外的視圖能夠從這個樹中移除。好比,每個tweet都包含了一個命名爲listElementBottom的 RelativeLayout。這個Layout包含了做者的名字,他的Twitter,從tweet發送出來以後已通過去的時間。名字和handle是 兩個分離的TextView代替了單獨一個TextView加入多種類型不一樣的spans,時間和icon使用一個TextView和一個 ImageView能夠被結合稱一個單獨的TextView,查看TextView's compound drawables   


左邊的菜單使用了多個LinearLayout+TextView+ImageView的組合來展現標籤和圖標。其實每一個可使用單獨一個 TextView就能夠代替了。

【如何扁平化你的UI:我解釋了不少關於這方面的技術。你能夠去看我在2009 Google I/O Talk


關於「輸入」事件:記不記得當咱們查看systrace而且發現,當處理觸摸事件的時候會有些卡頓?如今,是時候來追蹤這個 問題了,traceview是咱們去明晰系統正在作什麼的最好工具。

Traceview是一個記錄應用在調用某個方法花費多少時間的虛擬機分析器。能夠在ADT的DDMS視圖或者monitor中啓動他, 在Devices tab中選擇你應用進程,而後點擊Start method profiling按鈕。紅色環繞的三個箭頭。
在開啓追蹤以後,我來回滑動主時間軸,而且從新點擊按鈕來結束trace。你也能夠下載個人追蹤記錄:
結果以下圖截屏所示。


點擊第#21,ViewRootImpl.draw().高亮繪製時間。表格中最後一行給你一個這個方法的和在它的子類裏平均的調用時間 。如你使用高亮來仔細看這時間軸,你將會注意到在連續frames之間的間隙。

一個最簡單找出這些在這些間隙中到底發生了什麼方法就是(選擇他們其中一個的開始部分進行放大,而後點擊你能發 現的最大色塊)你追蹤父子鏈(parent chain)直到找到你能夠辨識出來的東西。在個人例子中,我追蹤一個花費了平 均時間的0.5ms的叫Patter.compileImpl,直到全部都指向了DBListAdapter.bindView。

顯然每次一旦有新的item被綁定或者滑動主時間軸時,應用都會從新一遍一遍的編譯這相同的正則表達式。Traceview展 示了綁定一個View平均花費38ms而且有56%的時間花費在解析HTML文本上。這看起來某些東西能夠被能夠在後臺實現而不 是阻塞UI線程,正則表達式不該該每次都要從新編譯。


接下來看你的了!
我留下最後一個trace做爲練習。這個應用在兩邊有兩個菜單,能夠經過敲擊時間線的左邊或者右邊來顯示。(在顯示這 菜單時GPU overdraws 高亮了過分繪製的部分,我已經使用Tracer for OpenGL來獲取了這個問題的幾幀。下載個人 trace而後看看你是否能找到什麼致使了overdraw(做者提示go to frame #34)。

提示就不翻譯了: Hints: the application should use hardware layers by calling View.setLayerType() to simplify drawing.  There are also extraneous backgrounds that can be optimized away with clever use of 9-patches. Clipping  could also be very helpful. Finally, maybe a ColorFilter set on a Paint passed to setLayerType() could  help remove the last drawing command.


我已經展現了多種你能夠用於優化你的應用的工具。我已經花費了大量的時間來描述在這些工具的幫助下,使用什麼技術去解決已辨別的問題。可是這個文章將會轉到一本書中。檢出文檔這官方文檔( Android developers web site)引用和全部GoogleI/O Android talks.
                                                                                                          ---Romain Guy 安全

【後語:最好使用Monitor,鄙人在使用ADT的時候老出錯。 性能優化




補Traceview操做圖:



session

app

相關文章
相關標籤/搜索