Google Developing for Android 三 - Performance最佳實踐


Google Developing for Android 三 - Performance最佳實踐

發表於 2015-06-07   |   分類於  Android最佳實踐

原文 Developing for Android, III:The Rules: Performanceandroid

在Android中,性能和內存的關係很密切,由於系統的總體內存大小會影響全部進程的性能,由於垃圾回收器會對運行期間的性能產生很大的影響。下面的重點是運行期間的性能問題而不是內存。web

避免在動畫和交互期間繁重的操做

正如在第一篇文章中提到過的,在UI Thread作繁重的操做會影響到渲染的處理。一樣會致使動畫的問題,由於它依賴於每一幀的渲染。這就意味着在動畫期間避免在UI進行繁重的操做就更加劇要。如下是一些能夠避免的常見狀況:數據庫

  • Layout
    Measurement 和 layout是比較繁重的操做,view的層級越複雜,操做就會越繁重。Measurement和layout是在UI Thred發發生的。所以當系統須要運行一個動畫的時候緊接着還需進行layout,而它們都是在同一個線程,所以動畫的流暢度可能就會受到影響。
    假設你的動畫在13ms內就能夠完成全部的渲染,在16幀率以內。而後某一請求致使了layout,花費了5ms的時間。該layout在下一幀繪製前會發生,那麼總的繪製時間就會達到18ms,最終你的動畫就明顯的跳過一幀。當動畫過程當中須要進行layout的時候,爲了不這種狀況,能夠在動畫啓動前進行layout或者延遲layout到動畫完成。固然,儘可能爲那些不會觸發layout的屬性添加動畫。好比,View的translationXtanshlationY屬性影響到post-layout屬性。LayoutParams 屬性也會須要請求layout操做,所以對這些屬性進行動畫的時候在相對複雜的UI上會致使卡頓。網絡

  • Inflation
    View 填充也只會發生在UI Thread,也是比較繁重的操做(View的層級越大,工做越繁重)。填充工做會在手動填充一個View 或者啓動一個activity的時候發生。這些都是在相同的UI線程進行的,當新的activity被填充的時候將會致使動畫暫停。爲了不這種狀況,能夠在動畫完成的時候再啓動Activity。或者避免滾動列表時填充不一樣類型的View致使的卡頓,能夠考慮預填充。好比,RecyclerView支持使用RecycledViewPool來裝載不一樣的View類型。併發

加快啓動速度

View的填充比較耗資源。不只要解析資源數據,還要實例化潛在的View以及它們所須要的數據,包括第一次須要的decode bitmap,layout和draw。UI越複雜,填充操做就會越繁重。app

上述全部都會下降啓動速度。當用戶啓動一個應用時時,但願等獲得一個及時的反饋說明應用已經在運行了。Android經過使用了一個「Starting Window」來弱化這種問題,該window經過應用主題和一些指定背景的圖片構成。這樣能夠很好的讓系統進程在後臺去進行加載和填充工做。當activity準備好展現的時候,starting window就會過渡到真實的內容緊接着用戶就可使用應用了。異步

然而,這種starting window應該給用戶更多的反饋以代表應用正在進行一些處理,固然這種策略不足以知足那種須要2秒甚至跟多時間去啓動的應用,用戶會被動的坐在那裏一直等到徹底加載完畢。工具

爲了啓動更快,一些不須要當即展現的UI能夠延遲加載。經過使用ViewStub能夠搞定。任什麼時候候都儘量的避免繁重的操做,好比進行大bitmap的decoding,避免因爲內存分配和回收產生的內存攪動。可使用工具監視啓動時間去解決瓶頸問題。佈局

避免在Application對象中初始化代碼。Application在每一次進程啓動的時候會被建立,會致使更多的工做而佔用了實際須要展現給用戶的UI的初始化時間。好比用戶正在瀏覽一張圖片,決定share,選中了你的app,那麼你的app須要作的就是展現給用戶分享的UI,其它都是多餘的。Application的子類更傾向在某些狀況下須要作一些耗時的操做,建議你選擇使用singletons去持有公共全局的狀態,這樣就會在它第一次被訪問的時候進行初始化。有一點相關的注意事項,不要在Application對象中進行網絡有關的操做。That object may be created when one of the app’s Services or BroadcastReceivers is started; hitting the network will turn code that does a local update at a specific frequency into a regular DDoS.post

還要注意,應用的不一樣狀態對於啓動時間有一個很大的區別。若是應用第一次啓動,那麼就會作大量的工做:啓動進程,初始化全部的狀態,必要的填充,佈局和繪製。若是應用已經啓動了而且在後臺存活,從新啓動就就很簡單。這兩種極端的例子會有另外兩種狀況出現,一:應用在用戶退出後還存在,可是任務須要從新建立(經過調用Activity.onCreaate()),二:進程被系統幹掉了,須要從新啓動該進程,可是任務能夠在Activity.onCreate()方法中經過保存的bundle恢復狀態。你在進行應用啓動時間測試的時候,確保優化最糟糕的狀況:進程被幹掉,須要從新啓動。你能夠經過從任務列表中移除你的應用來模擬這種狀況。

避免複雜的View層級

佈局越複雜,操做的時間就會越長:填充,佈局和渲染(一些潛在的無用內容的內存開銷,自定義View中多餘數據的引入)。尋找最節省資源的方式去展現嵌套的內容。一種方法就是使用自定義View或者自定義佈局,在自定義佈局中去避免複雜的嵌套,對於一個單獨的View來講繪製一些text和icons,相對於一個嵌套的ViewGroup就更簡單。如何在一個交互模塊中綁定多個元素呢?若是用戶能夠經過一個元素就能夠完成交互,那麼該元素應該是一個獨立的View,而不是和其它元素綁定在一塊兒。

避免在View層級的頂層使用RelativeLayout

RelativeLayout使用起來很方便,由於能夠任意指定View的相對位置。在不少時候,多是最好的選擇,可是相對佈局是消耗資源的一種方案,由於它須要兩次measurement去確保本身處理了全部的佈局關係。並且這個問題會伴隨着View層級中的ReativeLayout的增多,而變得跟嚴重。想象一下,一個頂部是RelativeLayout的佈局,原本就進行兩次的measurement工做,若是它的第一個child也是RelativeLayout,那麼該chilld RelativeLayout下面的佈局也要進行兩次measurement,整個佈局就要進行4次measurement。

在不須要RelativeLayout的一些屬性的時候,能夠選擇使用其它的佈局類型。好比LinearLayout或者自定義的佈局。確實須要對child進行相對佈局的時候,能夠考慮更優化的GridLayout,它已經預處理了Child View的關係,能夠避免double-measurement的問題。

避免在UI Thread 進行繁重的操做

在UI Thread中複雜的操做會致使動畫和繪製的延遲,最終會致使明顯的卡頓。一些已知的應該避免耗時操做的方法:onDrawonLayout,以及任何與View相關的在UI thread調用的相關方法。還有一些其它的操做,好比webservice的調用,網絡操做以及數據庫的操做。能夠考慮使用Loaders或者其它執行在其它線程的工具去操做,完成後再填充到UI上。一個能夠追蹤卡頓緣由的工具是StrictMode

另外一個在UI Thread中避免訪問文件系統和數據庫的緣由是:Android設備的存儲在處理多個併發的讀寫操做時支持的不夠好。即便你的app處理空閒狀態,可是其它的app可能正在執行繁重的I/O操做(Play Store更新apps)也可能會致使你的應用產生ANR或者一些比較大的延遲。

總的來講,全部的事情都應該是異步的,UI Thread應該只操做那些核心的UI 操做,好比處理View的屬性和繪製。

最小化 Wakeups

BroadcastReceivers能夠用於從其它應用接收那些指望響應的信息和事件。可是過多的響應以致於超過了自己所需的話,這些事件就會致使app常常被喚醒,最終致使整個設備的性能和資源的耗費。當你的應用不須要關心這些結果時,考慮關閉BroadcastReceivers,而且慎重選擇那些要響應的Intent。

爲低端手機考慮

大多數用戶的手機比開發者手機的配置要低。所以去爲這個市場的用戶開發就很重要。在關注性能問題的時候,不要以本身的手機水平做爲衡量標準,使用不一樣檔次的手機進行測試,確保你的應用能夠知足不一樣水平的設備。

低端手機的一些關注點還包括一些RAM的大小,屏幕的大小,好比512M的RAM或者768*480的屏幕分辨率的配置在低端手機中很常見。

使用Android提供的一些測試工具去追蹤重要的性能相關的信息:渲染性能(是否達到60的幀率?),內存分配(內存分配是否致使垃圾回收最終致使動畫的卡頓?),啓動性能(在第一啓動的時候是否作了太多的工做,致使用戶等過久?)找到這些問題,解決它們!

相關文章
相關標籤/搜索