標籤:
很多App都會遇到以下幾個常見的效能問題:
啟動速度慢;介面跳轉慢;事件響應慢;滑動和動畫卡頓。
一、啟動速度最佳化。
最佳化初始化任務:
1. 把一些初始化任務懶載入初始化
2. 把初始化任務並行化(非同步化)
3. 使初始化任務可以插拔(一個任務出問題不會影響到其他的任務)
其他:
1. 控制線程數量,注意線程的使用,用自己的線程池替換三方或者二方SDK的線程池,線程太多佔用cpu資源,
2. 使用緩衝來減少I/O操作(讀資料庫,讀檔案,SharedPreference)減少網路請求(判斷無網路直接返回)
3. 對於SharedPreference進行了專門的最佳化,減少單個檔案的大小,將毫無聯絡的儲存索引值分開到不同檔案中,
並且防止將大資料區塊儲存到SharedPreference中,這樣既不利於效能也不利於記憶體,
因為SharedPreference會有額外的一份緩衝長期存在。
4. Activity使用暖開機,在按Back鍵,不銷毀activity,釋放一些圖片等佔用記憶體大的資源
二、介面最佳化
布局複雜、過渡繪製多、Activity主要函數耗時、內容展示慢、介面重新布局(Layout)、GC次數
這些問題會導致介面卡頓。
1. 過度繪製
Activity使用預設主題背景,在layout中view盡量減少背景的設定(有前景內容,就不要設定和展示背景),
減少多層布局結構背景設定,減少Drawable的複雜Shape使用。
2. 最佳化布局層級
層級越多,測量和布局的時間就會相應增加,建立硬體列表的時間也會相應增加。
有時我們會嵌套很多布局來實現原本只要簡單布局就可以實現的功能,有時還會添加一些測試階段才會使用的布局。
通過刪除無用的層級,使用Merge標籤或者ViewStub標籤來最佳化整個布局效能。比如一些顯示錯誤介面、載入提示框介面等,
不是必須顯示的這些布局可以使用ViewStub標籤來提升效能。 另外要靈活使用布局,並不是層級越多就會效能越差,
有時候1層的RelativeLayout會比3層嵌套的LinearLayout實現的效能更糟糕。
除了靈活使用布局,另外我們還通過提前inflate以及線上程中做一些必要的inflate等來提前初始化布局,
減少實際顯示時候的耗時。對於一些複雜的布局,做複用池,減少inflate帶來的效能損耗,特別是在列表中。
3. 加快介面展示
1. 減少主線程的GC停頓,因為即使並行GC,也會對heap加鎖,如果主線程請求分配記憶體的話,也會被掛起,
避免在onDraw中頻繁分配較多和較大的對象,去掉ListView ,ScrollView等控制項的EdgeEffect效果,來減少記憶體配置和加快控制項的建立時間
2. 可以通過TraceView工具找出主線程的耗時操作以及操作次數和其他耗時的線程並作最佳化;
3. 對於網路請求,做好本機快取,在網速慢或者無網路的時候展示,減少不必要的資料協議欄位,減少名字長度等,並作壓縮。
還可以通過分頁載入資料來加快傳輸解析時間。因為JSON越大,傳輸和解析時間也會越久,引發的記憶體對象分配也會越多;
4. 注意線程的優先順序,對於佔用CPU較多時間的函數,也要判斷線程的優先順序。
5. 重寫方法requestLayout、onSizeChanged,如果大小沒有變化就阻斷過多Layout請求。
4. 減少GC
1.減少對象分配,找出不必要的對象分配,如可以使用非封裝類型的時候,使用了封裝類型;字串的+號和擴容;減少Handler.post(Runnable r)等頻繁使用。
2. 對象的複用,對於頻繁分配的對象需要使用複用池。
3. 儘早釋放無用對象的引用,特別是大對象和集合對象,通過置為NULL,及時回收。
4. 防止泄露,除了最基本的檔案、流、資料庫、網路訪問等都要記得關閉以及unRegister自己註冊的一些事件外,還要盡量少的使用靜態變數和單例。
5. 控制finalize方法的使用,在高頻率函數中使用重寫了finalize的類,會加重GC負擔,使得效能上有幾倍的差別。
6. 合理選擇容器,在效能上優先考慮數組,即使我們現在習慣了使用容器,也要注意頻繁使用容器在效能上的隱患點:首先是擴容開銷, HashMap擴容時重新Hash的開銷較大。其次是記憶體開銷,HashMap需要額外的Map.Entry對象分配 ,需要額外記憶體,也容易產生更多的記憶體片段。SparseArray和ArrayList等在記憶體方面更有優勢。再次是遍曆,對於實現了RandomAccess介面的容器如ArryList的遍曆,不應該使用foreach迴圈。
5. 用效能分析工具採集資料,分析資料,找出效能最佳化點
通過Memory Monitor查看記憶體波動和GC情況,還可通過AlloCation Tracker工具觀察記憶體的分配,發現很多小對象的分配問題。
利用Trace For OpenGL工具找出介面上導致硬體加速耗時的點,例如一些圓角圖片的處理等。
使用TraceView分析方法耗時,開啟GPU過度繪製監視以及GPU呈現模式使用Systrace分析介面渲染問題。
6. 編碼時最佳化點
靈活使用final關鍵字,避免在迴圈中使用try catch,盡量少用Enum類型,可以使用臨時變數代替this.member等
7. 測試啟動時間方式
log方式在oncreate和onwindowFocus打點,記錄Activity啟動到介面展示的時間
可以使用hock方式記錄啟動時間,使用測試網站來測試,
android 5.0以上 使用adb shell am start -W 來測試時間。
Android效能最佳化篇