Android 性能典范:拯救計劃
前言
今天逛稀土時偶然看到 hanks 分享的一篇英文文章,粗略瀏覽便已覺得不錯,因此翻譯成中文,與君分享。
原文地址: Android Performance Patterns: Rescue tips
正文
現在的app到處都充斥著華麗的動畫、復雜的轉化還有自定義View,然而用戶體驗必須盡可能直觀且類似。以下這些范例將會幫助你做出一個流暢的、快速響應的、甚至可能減少電量損耗的app,這些范例由一些可以提升整體應用表現的微優化組成。
避免“壞”表現
- 避免堵塞主線程
- 避免可能引發大范圍重繪的不必要的重繪
- 用 RelativeLayout 來減少布局層級
- 避免在 LinearLayout 中使用嵌套的 weight 屬性(因為weight屬性會使每個子View進行兩次measure)
- 避免使用沒有恰當處理的自定義View
- 避免創建沒必要的對象
- 將常量聲明為 static final(static比普通變量快 15% - 20%)
- 使用基本數據類型(Integer、Float 比基本類型慢兩倍)
- 避免內部的 getter 和 setter(直接訪問屬性可以快3倍)
- 使用改進的循環語法【譯者注:這里應該是指for each循環】
- 對私有的內部類考慮使用包訪問級別代替私有訪問級別
- 謹慎使用native方法
自定義View
- 遵循KISS原則
- 在布局中使用merge標簽來作為根標簽(避免額外的ViewGroup)
- 使用include標簽(便于布局的復用)
- 避免不必要的布局
- 不要在onDraw中申請內存或者做復雜邏輯
- 去除不必要的invalidate()調用
- 考慮創建自己的ViewGroup
- 用RecyclerView替代ListView和GridView
避免內存抖動
1, 不可變對象:String
- 不要申請大量不必要的對象內存:
- 2, 自動裝箱:Integer, Boolean...
- 考慮使用對象池并緩存來減少內存抖動
- 留心enum類型的開銷(一個指向枚舉類型的引用就要占據4個字節)
避免內存泄漏
- 不要在內部類里泄漏context實例
- 不要在activity里泄漏view實例
- 使用內部靜態類優于非靜態的
- 除非鍵都是WeakReference,否則不要使用WeakHashmap作為緩存
CPU
- 不要嵌套多通路布局
- 當需要時才去進行復雜的計算【譯者注:類似懶加載】
- 緩存復雜計算的結果以復用
- 考慮 RenderScript 的性能
- 盡可能減少主線程的工作
避免過度繪制
- 精簡drawable
- 在透明部分使用.9圖
- 設置view的透明度時多注意
- 去除view中無用的背景
bitmap
- 將bitmap解碼為需要的尺寸:BitmapFactory.Options(
- inSampleSize, inDensity, inTargetDensity)
- 加載bitmap到內存時,設置尺寸為顯示尺寸
- 如無必要不要進行縮放
- 使用LRU緩存
Service
- 除非Service在處理事務否則不要讓其保持運行。同時也要小心stopService當Service工作完成時
- 系統傾向保留有Service運行的進程,那么被service占用的內存將無法被其他進程使用或者被內存置換
- 限制service生命周期的最佳實踐是使用IntentService,它會在工作完成后結束自身
- 讓沒必要存活的Service繼續運行是Android app內存管理最差的舉動之一
線程
在線程的run()方法中使用
- Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND)可以減少該線程及UI線程的計算性能損耗
- 如果你沒有通過這種方式為線程設置低優先級,那么該線程仍會拖慢你的app,因為默認情況下它的優先級與UI線程的優先級相同
- 維護住當前線程的引用,以便你之后可能先打斷該線程。例如:當網絡連接失敗你可以取消該線程
避免ANR
- UI線程中做的事越少越好
- 如果應用正在后臺響應用戶的輸入,最好顯示進度給用戶(例如顯示一個進度條)
- 使用Systrace或Traceview等性能工具來檢測應用響應能力的瓶頸
- 如果你的應用有一個非常耗時的初始化過程,考慮使用啟動頁或者盡快渲染主要的view,表明正在加載中并且正在顯示異步的信息
本文由用戶 gysjxn 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!