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