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。

現組建了一個Android的大圈子,內有大神小白起飛,圈內會不定時更新一些Android中高級的進階資料,歡迎大家帶著技術問題來討論,共同成長進步!(包含資深UI工程師,Android底層開發工程師,Android架構師,原生性能優化及混合優化,flutter專精);

歡迎點贊+私信我 資料 即可加入~

推薦閱讀:

安卓推送的那些事兒
所謂的安卓aso優化技巧原來是這樣子的
騷年你的屏幕適配方式該升級了!-SW 限定符適配方案

TAG:Android開發 | 安卓優化 | 程序員 |