本篇重點是性能優化,包括內容:
- 布局優化
- 繪制優化
- 內存泄漏優化
- 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弱引用;當外部類結束生命周期時清空消息隊列。
-
線程導致的內存泄漏
- 詳情:AsyncTask/Runnable以匿名內部類的方式存在,會隱式持有對所在Activity的引用。
- 解決辦法:將AsyncTask和Runnable設為靜態內部類或獨立出來;在線程內部采用弱引用保存Context引用。
- 資源未關閉導致的內存泄漏
- 詳情:未及時注銷資源導致內存泄漏,如BraodcastReceiver、File、Cursor、Stream、Bitmap等。
- 解決辦法:在Activity銷毀的時候要及時關閉或者注銷。
-
BraodcastReceiver:調用
unregisterReceiver()
注銷; -
Cursor,Stream、File:調用
close()
關閉; -
Bitmap:調用
recycle()
釋放內存(2.3版本后無需手動)。
-
BraodcastReceiver:調用
- Adapter導致的內存泄漏
- 詳情:不使用緩存而只依靠
getView()
每次重新實例化Item,會給gc制造壓力。 - 解決辦法:在構造Adapter時使用緩存的convertView。
- 詳情:不使用緩存而只依靠
c.方式:
- 在開發過程中避免寫出內存泄漏的代碼,可參考以上多種解決辦法。
- 通過分析工具如MAT尋找潛在的內存泄漏。
推薦閱讀:常見的內存泄漏原因及解決方法
4.響應速度優化
a.核心思想:避免在主線程中做耗時操作。
b.方式:開線程。
5.ListView優化
- 復用ViewHolder,具體使用;
- 不要在
getView()
中執行耗時操作; - 開啟硬件加速。
綜合實例:提高ListView性能的技巧
6.Bitmap優化
- 利用BitmapFactory.Options的inSampleSize屬性,根據需求對圖片進行采樣后再加載進來。詳見Bitmap的高效加載
7.線程優化
- 采用線程池,避免存在大量的Thread。詳見線程&線程池
8.其他
- 避免創建過多的對象 ;
- 不要過多使用枚舉,枚舉占用的內存空間要比整型大;
- 常量請使用static final來修飾;
- 使用一些Android特有的數據結構,比如SparseArray和Pair等,它們都具有更好的性能;
- 適當使用軟引用和弱引用;
- 采用內存緩存和磁盤緩存;
- 盡量采用靜態內部類,這樣可以避免潛在的由于內部類而導致的內存泄露。
推薦閱讀:Android開發性能優化總結、 Android最佳性能實踐系列
最后,是有助于提高程序可維護性的幾點建議,一起共勉:
希望這篇文章對你有幫助~