要點提煉|開發藝術之效能優化

釐米姑娘發表於2018-01-01

本篇重點是效能優化,包括內容:

  • 佈局優化
  • 繪製優化
  • 記憶體洩漏優化
    • MAT工具
  • 響應速度優化
  • ListView優化
  • Bitmap優化
  • 執行緒優化
  • 其他

1.佈局優化

a.核心思想:儘量減少佈局檔案的層級

b.方式:

  • 多巢狀情況下可使用RelativeLayout減少巢狀。
  • 佈局層級相同的情況下使用LinearLayout,它比RelativeLayout更高效。
  • 使用<include>標籤重用佈局、<merge>標籤減少層級、<ViewStub>標籤懶載入。詳見佈局篇--佈局原則

補充例項 Android最佳效能實踐--佈局優化技巧


2.繪製優化

a.核心思想:避免在View.onDraw()中執行大量的操作。

b.方式:

  • 避免建立新的區域性物件,因為onDraw()可能被多次呼叫而產生大量的臨時物件,導致佔用過多記憶體、系統頻繁gc,降低了執行效率。
  • 避免做耗時任務,以及大量迴圈操作。

3.記憶體洩漏優化

a.記憶體洩漏(Memory Leak):程式在申請記憶體後,無法釋放已申請的記憶體空間。是造成應用程式OOM的主要原因之一。

記憶體溢位(out of memory):指程式在申請記憶體時,沒有足夠的記憶體空間供其使用。

補充閱讀記憶體溢位和記憶體洩漏的區別

b.可能原因:

  • 靜態變數導致的記憶體洩漏
    • 詳情:一個靜態變數又是非靜態內部類會一直持有對外部類的引用,導致外部類Activity無法被回收。
    • 解決辦法:將內部類設為靜態內部類或獨立出來;使用context.getApplicationContext()
  • 單例模式導致的記憶體洩漏
    • 詳情:單例傳入引數this來自Activity,使得持有對Activity的引用。
    • 解決辦法:傳參context.getApplicationContext()
  • 屬性動畫導致的記憶體洩漏
    • 詳情:沒有在onDestroy()中停止無限迴圈的屬性動畫,使得View持有了Activity。
    • 解決辦法:在Activity.onDestroy()中呼叫Animator.cancel()停止動畫。
  • Handler導致的記憶體洩漏
    • 詳情:Message持有對Handler的引用,而非靜態內部類的Handler又隱式持有對外部類Activity的引用,使得引用關係會保持至訊息得到處理,從而阻止了Activity的回收。
    • 解決辦法:使用靜態內部類+WeakReference弱引用;當外部類結束生命週期時清空訊息佇列。
  • 執行緒導致的記憶體洩漏
  • 資源未關閉導致的記憶體洩漏
    • 詳情:未及時登出資源導致記憶體洩漏,如BraodcastReceiver、File、Cursor、Stream、Bitmap等。
    • 解決辦法:在Activity銷燬的時候要及時關閉或者登出。
  • Adapter導致的記憶體洩漏

c.方式:

  • 在開發過程中避免寫出記憶體洩漏的程式碼,可參考以上多種解決辦法。
  • 通過分析工具如MAT尋找潛在的記憶體洩漏。

推薦閱讀常見的記憶體洩漏原因及解決方法


4.響應速度優化

a.核心思想:避免在主執行緒中做耗時操作。

b.方式:開執行緒


5.ListView優化

  • 複用ViewHolder,具體使用
  • 不要在getView()中執行耗時操作;
  • 開啟硬體加速。

綜合例項ListView終極優化方法


6.Bitmap優化

  • 利用BitmapFactory.Options的inSampleSize屬性,根據需求對圖片進行取樣後再載入進來。詳見Bitmap的高效載入

7.執行緒優化


8.其他

  • 避免建立過多的物件 ;
  • 不要過多使用列舉,列舉佔用的記憶體空間要比整型大;
  • 常量請使用static final來修飾;
  • 使用一些Android特有的資料結構,比如SparseArray和Pair等,它們都具有更好的效能;
  • 適當使用軟引用和弱引用;
  • 採用記憶體快取和磁碟快取;
  • 儘量採用靜態內部類,這樣可以避免潛在的由於內部類而導致的記憶體洩露。

推薦閱讀Android開發效能優化總結Android最佳效能實踐系列


最後,是有助於提高程式可維護性的幾點建議,一起共勉:


希望這篇文章對你有幫助~

相關文章