Android App性能優化技能,看這篇就夠了
一.何為App的性能
拿小車舉例,大家知道什麼是一輛小車的性能嗎?同學甲說,是否省油、加速是否夠快、開起來是否穩定、安全等等。
沒錯,那就是小車的性能。
那App的性能又是指什麼呢?同學乙說,App啟動是否夠快,運行是否流暢,是否省電、省流量,安裝包體積是否夠小等等。
是的,這就是App的性能。
二.關注App性能,有什麼用
我們知道,一輛小車性能越好,加速越快,跑的越穩,越省油。
App也一樣,性能越好,運行更流暢、更穩定、更省流量、電量,包的體積也會更小,這能給用戶帶來優秀的體驗,進而也會提升App的知名度。
既然App性能那麼重要,那我們就要掌握App性能優化的技能了。
三.如何進行App性能優化
掌握App性能優化,是Android開發人員進階中高級的必備技能。那如何進行App的性能優化呢?
我們可以從這幾個方面入手:卡頓優化、內存優化、穩定性優化、耗電優化、安裝包大小優化、資料庫SQLite優化、網路優化。
接下來,我們逐一展開講解。
1.卡頓優化
1.1卡頓場景
可分為四個大的方向:
1.1.1UI
UI包括繪製和渲染。
1.1.2啟動
啟動可分為冷啟動、熱啟動。
1.1.3跳轉
跳轉包括頁面間跳轉和前後台切換。
1.1.4響應
包括:點擊、滑動、系統事件、按鍵。
1.2卡頓原因
可分為以下兩方面原因:
1.2.1繪製任務太重
首先,我們要明白這樣一個概念,人類肉眼在看每秒60幀(即:每幀16ms)的畫面時,是不會感受畫面卡頓,當低於60幀/秒,我們就會感受到畫面卡頓了。
Android系統每隔16ms就發出Vsync,觸發對UI的渲染。如果每次都在<=16ms內完成渲染,界面就會流暢;如果每次都在>16ms才能完成渲染,就會造成丟幀,界面就會卡頓。
1.2.2主線程耗時操作
主要包括數據處理耗時,數據處理佔用CPU過高,內存增加導致頻繁GC等。
1.3分析工具
Hierarchy View,Profile GPU Rendering,TraceView,Systrace
1.4優化手段
1.4.1布局優化
減少布局層級嵌套,布局復用,刪除無用屬性,使用ViewStub提高顯示速度。
1.4.2避免過度繪製
常用布局的優化,自定義View的優化。
1.4.3啟動優化
UI布局,邏輯載入優化,數據準備策略優化。
1.4.4合理的刷新機制
減少刷新次數,縮小刷新區域,避免後台有較高的CPU線程運行。
其他:比如,使用動畫效果,根據不同場景選擇合適的動畫框架實現。有些情況,可以使用硬體加速來提高流暢度。
2.內存優化
2.1Android內存管理機制
Android應用都是在Android虛擬機上運行的,內存分配和垃圾回收都是由Android虛擬機來完成的。
2.1.1Java對象的聲明周期
創建-使用-銷毀(包括:不可見-不可達-收集-終結-對象再分配)。
Android系統內存分配,實際上是對堆的分配和釋放。
2.1.2內存回收機制
年輕代、老年代、持久代。
年輕代
所有新生成的對象都放在年輕代。
年輕代分為一個Eden區和兩個Survivor區。
GC時,當Eden區滿時,還存活的對象會被複制到其中一個Survivor區(A)。
當這個Survivor區(A)也滿時,就會被複制到另一個Survivor區(B)。
當Survivor區(B)也滿時,從第一個Survivor(B)複製過來並且還存活的對象,就會被複制到老年代。
老年代
在年輕代經歷了N次垃圾回收仍然存活的到對象,就被放到老年代。
持久代
主要存放靜態文件,比如Java類,方法等。
持久代對垃圾回收沒有明顯影響。
如果持久代空間太小,可通過-XX:MaxPermSize =< N配置。
2.2內存泄露場景
資源類的對象未關閉。
註冊系統事件未註銷:使用Sensor Manager等系統服務,Context.getSystemService(int name)獲取系統服務。
類的靜態變數持有大數據對象:如,activity的靜態變數持有該activty的引用。
非靜態內部類的靜態實例。
Handler造成內存泄漏。
WebView。
匿名類:new AsyncTask,new Thead,TimerTask。這些匿名類對象結束之前一直持有對應activity的引用,導致activity實例無法被回收,造成內存泄漏。
2.3分析工具
Memory Monitor,Heap Viewer,Allocation Tracker,Memory Analyzer Tool,LeakCanary。
2.4優化手段
2.4.1對象引用
根據實際需求,合理使用強引用,軟引用,弱引用,虛引用。
2.4.2減少不必要的內存開銷
增加內存復用:比如合理使用系統自帶的資源,視圖,圖片,對象池等的復用。
留意自動裝箱。
2.4.3使用最優數據類型
使用最優數據類型,比如使用ArrayMap,避免使用枚舉類型,使用LruCache等。
2.4.5圖片內存優化
圖片壓縮,圖片緩存。
3.穩定性優化
3.1異常場景
Crash,ANR。
3.2分析工具
穩定性主要依賴代碼優化,邏輯實現的優化來提升。所以從代碼層面來看,分析工具主要有:Android Lint,Findbugs,Checkstyle,PMD,FireLine。
3.3優化手段
3.3.1提高代碼質量。
3.3.2代碼掃描。
3.3.3Crash監控。
3.3.4Crash上報機制。
4.耗電優化
4.1耗電後果
App耗電嚴重,會給用戶帶來非常差的體驗,導致用戶卸載應用。
4.2優化手段
4.2.1Battery Historian
這是Google出的Android系統電量分析工具。
4.2.2計算優化
避免浮點運算等等。
4.2.3避免WakeLock不當使用。
4.2.4使用Job Schedule。
5.安裝包大小優化
5.1優化體積大小的原因
節省流量,提高用戶對App的好感度。
5.2優化手段及工具
5.2.1代碼混淆
使用ProGuard工具進行壓縮,優化,混淆。ProGuard的原理:壓縮,優化,混淆。
5.2.2資源優化
使用Android Lint刪除冗餘資源,使資源文件最小化。
5.2.3圖片優化
使用AAPT,TinyPng壓縮圖片,使用webP圖片格式等。
5.2.4避免引入重複功能的庫
對比選擇最優庫,不要引入多個類似功能的庫。如果有相關庫的源碼,可根據實際需求,抽取需要的代碼重新編譯庫,讓庫儘可能的小。
5.2.5插件化
可將功能模塊放伺服器,需要用時再載入。
文章APK極限壓縮:
mp.weixin.qq.com/s?__biz=MzA…
6.資料庫SQLite優化
6.1優化手段
6.1.1索引
概念:
索引是對資料庫表中一列或多列數據進行排序的一種數據結構。可理解為一個指向表中數據的指針,與一本書的目錄類似。
優點:
加快表中數據查詢速度。
缺點:
創建索引本身也會造成資源開銷。
類別:
表索引:CREATE INDEX index_name ON table_name。
單列索引:CREATE INDEX index_name ON table_name(column_name)。
唯一索引:CREATE UNIQUE INDEX index_name ON table_name(column_name)。
組合索引:CREATE INDEX index_name ON table_name(column1,column2)。
主鍵索引:ALTER TABLE table_name ADD CONSTRAINT index_name PRIMARY KEY(primaryKey)。
總結:
合理使用索引,可加快資料庫表數據的查詢速率。
6.1.2事務
概念:
對資料庫原子性的操作。
優點:
為數據的整體性執行帶來可靠安全性,為更新和刪除操作帶來很大優化。
總結:
保證數據的完整性,安全性,提高數據更新,刪除操作的效率。
6.1.3其他手段
盡量少用cursor.getColumnIndex()。
用StringBuilder(非線程安全)或StringBuffer(線程安全)來拼接字元串。
查詢時,只返回需要的數據或結果。
cursor使用後要及時關閉。
7.網路優化
7.1原因
網路優化不好,造成用戶流量消耗大,耗電快,用戶等待時間長體驗差等。
7.2工具
Network Monitor,Charles,Fiddler,Stecho。
7.3優化手段
7.3.1介面設計
API設計要合理。
使用GZIP壓縮。
選擇合適的數據格式:json,xml,protocol Buffer。
7.3.2圖片處理
圖片下載:
使用縮略圖。
使用WebP圖片。
根據設備規格,指定圖片尺寸請求圖片。
使用完善的合適的圖片載入框架:Glide,Picasso等。
圖片上傳:一般要支持斷點續傳。
7.3.3網路緩存
適當緩存,可讓App看起來更快。
使用DiskLruCache。
7.3.4打包網路請求
網路狀況好(如:WiFi狀態下),可一次非同步發起多個業務模塊的數據請求。
7.3.5監聽相關狀態變化
休眠狀態(即:熄屏狀態下),盡量不要發起網路請求。
充電狀態,可適當做一些必要的網路請求,但要控制頻率。
弱網狀態下,可壓縮和減少數據傳輸量;不要自動載入圖片,用占點陣圖顯示;頁面視圖先顯示,網路請求延遲提交。
7.3.6優化網路請求機制
劃分網路請求的優先順序,同一頁面,同一模塊,重要的數據優先請求。
網路差,減少請求量;網路好,提高請求量。
合併網路請求,減少請求次數。比如,本地埋點數據,無需實時上報,可先本地緩存,再根據上報策略,選擇合適時機一併上報。
7.3.8IP直連和HttpDns
IP直連,省去DNS解析時間。
使用HttpDns,防止運營商域名劫持或跨網訪問問題。
7.3.9優化請求頻率
使用本地緩存,讓App在離線狀態也能使用。
優先使用緩存;當沒有緩存或緩存國旗,再請求網路數據。
App性能優化,是一個持續地過程,需要我們不斷提高自己性能優化的能力,才能提高App的性能,才能打造出」快,省,穩」的極佳體驗App。