Android性能優化學習 最近公司主抓性能優化工作,藉此春風也學習到了許多Android性能優化方面的知識。由於組內隊友的給力,優化的成果也是比較喜人。同時也學習和實踐了不少知識,特此記錄。 1.性能優化分析工具學習 在開始代碼優化之前,先得學會使用性能分析工具。以下三個工具都是谷歌官方推出的,可 ...
Android性能優化學習
最近公司主抓性能優化工作,藉此春風也學習到了許多Android性能優化方面的知識。由於組內隊友的給力,優化的成果也是比較喜人。同時也學習和實踐了不少知識,特此記錄。
1.性能優化分析工具學習
在開始代碼優化之前,先得學會使用性能分析工具。以下三個工具都是谷歌官方推出的,可以幫助我們定位分析問題,從而優化我們的APP。
- System Trace
Systrace是一個收集和檢測時間信息的工具, 它能顯示CPU和時間被消耗在哪兒了, 每個進程和線程都在其CPU時間片內做了
什麼事兒. 而且會指示哪個地方出了問題, 以及給出Fix建議。給出的結果trace文件是以html形式打開的,直接用瀏覽器打開
查看十分方便。打開方法:打開DDMS後,連接手機,點擊手機上方一排按鈕中的SysTrace按鈕。
打開的效果如下圖:
在代碼中打點方式如下
- Hierarchy Viewer
Hierarchy Viewer提供了一個可視化的界面來觀測佈局的層級, 讓我們可以優化佈局層級, 刪除多餘的不必要的View
層級, 提升佈局速度。另外,開發者模式中調試GPU過度繪製選項也可以進行視圖層級調試。在SDK-> tools目錄下
打開hierarchyviewer.bat即可。
效果如下圖:
- TraceView
一個圖形化的工具, 用來展示和分析方法的執行時間。也是一款性能優化的神器。可以通過像打log一樣的方式去定位代碼的執行時
間,從而可以準確定位是哪一段代碼的執行消耗了太多時間。相比SysTrace,功能更強大,使用起來也更複雜。
2.佈局優化
佈局優化相對比較容易,優化可以先從佈局來展開。使用Hierarchy Viewer和開發者模式中關於佈局繪製的選項,可以查到一些問題然後進行修改。
-
佈局嵌套過深 有的時候為了趕進度,佈局設計的不是很好。層級嵌套過深的話,深度遍歷各個節點會非常消耗時間,這也是佈局優化餘地最大的一個點了。很多過深的層級是不必要的。如果佈局真的很複雜,不深度嵌套沒法實現想要的效果。試試最新的約束佈局Constraintlayout吧。沒有使用過的話,下麵這篇官方文檔可以幫助你:
Constraintlayout官方介紹文檔 -
使用合適的佈局 三種常見的ViewGroup的繪製速度:FrameLayout > LinerLayout > RelativeLayout。當然,如果用RelativeLayout可以避免佈局嵌套的話是值得的。可以根據這些去決定選用什麼樣的佈局。
-
列表控制項優化 不論是ListView還是RecycleView都有優化點,一個是convertView的復用,一個是ViewHolder的使用避免重覆遍歷節點。當然這些都是基礎中的基礎了。如果發現項目中的代碼ListView或者RecycleView的使用不規範的話,趕緊進行修改吧。
-
使用include標簽 在佈局文件中,<include>標簽可以指定插入一段佈局文件到當前佈局。這樣的話既提高了佈局復用,也減少了我們的代碼書寫。另外,<merge>標簽可以和<include>的標簽一起使用從而減少佈局層級。
-
ViewStub延時載入 有些佈局,比如網路出錯的佈局,沒必要在所有時候都載入出來。使用ViewStub可以實現按需載入。ViewStub本身沒有寬高,載入起來幾乎不消耗什麼資源。當對他setVisibility(View.VISIBLE)的時候會調用它引用的真實佈局填充到當前位置,從而實現了延時載入,節省了正常載入的時間。
-
移除Activity預設背景 只要我們不需要Activity的預設背景,就可以移除掉,以減少Activity啟動時的渲染時間,提升啟動效率。移動方法見下:
3.線程優化
線程的創建和銷毀會帶來比較大的性能開銷。因此線程優化也很有必要。查看項目中是否存在隨意new thread,線程缺乏管理的情況。使用AsyncTask或者線程池對線程進行管理,可以提升APP的性能。另外,我比較推薦使用Rxjava來實現非同步操作,既方便又優雅。
4.記憶體泄露
記憶體泄露會導致APP占用記憶體過高,影響效率,嚴重的話會導致OOM。因此如果項目存在記憶體泄露的話要優先解決。查找記憶體泄露可以用LeakCanary等工具,具體怎麼解決,有哪些泄露點,以後有時間也寫篇總結。
5.演算法優化
毋庸置疑,使用合適的演算法處理事務可以大幅提升APP的性能。當然演算法不是我的強項,也只能給出一些大致的點:查詢考慮二分查找節省時間,儘量不要使用耗時的遞歸演算法。必要的時候可以空間換時間來提高APP運行效率。
6.其他優化點
-
非同步處理耗時任務 在Activity、Fragemnt的onCreate等初始化方法中,如果執行了太耗時的操作(例如讀取各種數據),會影響頁面的載入速度,讓用戶覺得APP太慢。這時候可以非同步處理這些耗時任務,減小應用啟動的時候的負擔。
-
替換矢量圖 儘管矢量圖有諸多優點,但矢量圖的繪製是消耗性能的。在應用初始化載入等比較影響用戶體驗的地方,還是建議使用Bitmap來代替矢量圖,提高APP開啟效率。
-
正則表達式 經小伙伴用TraceView不斷的打點發現,正則表達式非常消耗時間。因此儘管正則表達式非常優雅,涉及到性能問題的時候,可以改為其他判斷方式來提高APP性能。
-
浮點類型 在Java中浮點類型的運算大概比整型數據慢兩倍,因此整型數據能解決的問題儘量用整型。
-
減少冗餘log 開發的時候用於調試的log,在項目上線的時候沒用的要及時刪除。當然有用的log還是要留下,以便以後分析問題。
-
刪除無用資源 沒用用的資源會增大APK大小,既然沒有用了,上線的時候當然要及時刪除。
-
Lint代碼檢查 使用Lint等靜態代碼檢查工具可以幫助我們發現很多隱藏的問題。Lint檢查出來的問題越少,說明代碼越規範,越不容易出現各種問題,APP性能自然也會提升。
-
濫用全局廣播 全局廣播也是十分消耗性能的一個點。對於應用內的通訊,使用介面回調,EventBus等手段比起廣播是更好地選擇。動態註冊廣播的時候,也不要忘了廣播的註銷。
7.總結
可以看到除了工具的使用外,性能優化是很考驗代碼功底的。因此想要做好性能優化,強化基本功不可少。性能優化也是一件相對枯燥而難度大的工作。因為很多優化的努力可能立馬看不到效果,或者說優化的成果在數據上難以體現。我們在做性能優化的時候也遇到果瓶頸,找不到優化方向而感到泄氣。但是堅持下來,利用好工具,從各個點去優化,總會有撥開雲霧見青天的一天!
作者:業松
鏈接:https://www.jianshu.com/p/31485a3cf5ca
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。