Android App效能優化技能,看這篇就夠了

NickSong發表於2019-04-28

一.何為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。

加油~~


大家有好的建議和看法,都歡迎在評論區留言,一起交流學習,謝謝?。

相關文章