Android App性能優(yōu)化技能,看這篇就夠了

一.何為App的性能

拿小車舉例,大家知道什么是一輛小車的性能嗎?同學(xué)甲說,是否省油、加速是否夠快、開起來是否穩(wěn)定、安全等等。

沒錯(cuò),那就是小車的性能。

那App的性能又是指什么呢?同學(xué)乙說,App啟動(dòng)是否夠快,運(yùn)行是否流暢,是否省電、省流量,安裝包體積是否夠小等等。

是的,這就是App的性能。

二.關(guān)注App性能,有什么用

我們知道,一輛小車性能越好,加速越快,跑的越穩(wěn),越省油。

App也一樣,性能越好,運(yùn)行更流暢、更穩(wěn)定、更省流量、電量,包的體積也會(huì)更小,這能給用戶帶來優(yōu)秀的體驗(yàn),進(jìn)而也會(huì)提升App的知名度。

既然App性能那么重要,那我們就要掌握App性能優(yōu)化的技能了。

三.如何進(jìn)行App性能優(yōu)化

掌握App性能優(yōu)化,是Android開發(fā)人員進(jìn)階中高級(jí)的必備技能。那如何進(jìn)行App的性能優(yōu)化呢?

我們可以從這幾個(gè)方面入手:卡頓優(yōu)化、內(nèi)存優(yōu)化、穩(wěn)定性優(yōu)化、耗電優(yōu)化、安裝包大小優(yōu)化、數(shù)據(jù)庫SQLite優(yōu)化、網(wǎng)絡(luò)優(yōu)化。

接下來,我們逐一展開講解。

1.卡頓優(yōu)化

1.1卡頓場景

可分為四個(gè)大的方向:

1.1.1UI

UI包括繪制和渲染。

1.1.2啟動(dòng)

啟動(dòng)可分為冷啟動(dòng)、熱啟動(dòng)。

1.1.3跳轉(zhuǎn)

跳轉(zhuǎn)包括頁面間跳轉(zhuǎn)和前后臺(tái)切換。

1.1.4響應(yīng)

包括:點(diǎn)擊、滑動(dòng)、系統(tǒng)事件、按鍵。

1.2卡頓原因

可分為以下兩方面原因:

1.2.1繪制任務(wù)太重

首先,我們要明白這樣一個(gè)概念,人類肉眼在看每秒60幀(即:每幀16ms)的畫面時(shí),是不會(huì)感受畫面卡頓,當(dāng)?shù)陀?0幀/秒,我們就會(huì)感受到畫面卡頓了。

Android系統(tǒng)每隔16ms就發(fā)出Vsync,觸發(fā)對UI的渲染。如果每次都在<=16ms內(nèi)完成渲染,界面就會(huì)流暢;如果每次都在>16ms才能完成渲染,就會(huì)造成丟幀,界面就會(huì)卡頓。

1.2.2主線程耗時(shí)操作

主要包括數(shù)據(jù)處理耗時(shí),數(shù)據(jù)處理占用CPU過高,內(nèi)存增加導(dǎo)致頻繁GC等。

1.3分析工具

Hierarchy View,Profile GPU Rendering,TraceView,Systrace

1.4優(yōu)化手段

1.4.1布局優(yōu)化

減少布局層級(jí)嵌套,布局復(fù)用,刪除無用屬性,使用ViewStub提高顯示速度。

1.4.2避免過度繪制

常用布局的優(yōu)化,自定義View的優(yōu)化。

1.4.3啟動(dòng)優(yōu)化

UI布局,邏輯加載優(yōu)化,數(shù)據(jù)準(zhǔn)備策略優(yōu)化。

1.4.4合理的刷新機(jī)制

減少刷新次數(shù),縮小刷新區(qū)域,避免后臺(tái)有較高的CPU線程運(yùn)行。

其他:比如,使用動(dòng)畫效果,根據(jù)不同場景選擇合適的動(dòng)畫框架實(shí)現(xiàn)。有些情況,可以使用硬件加速來提高流暢度。

2.內(nèi)存優(yōu)化

2.1Android內(nèi)存管理機(jī)制

Android應(yīng)用都是在Android虛擬機(jī)上運(yùn)行的,內(nèi)存分配和垃圾回收都是由Android虛擬機(jī)來完成的。

2.1.1Java對象的聲明周期

創(chuàng)建-使用-銷毀(包括:不可見-不可達(dá)-收集-終結(jié)-對象再分配)。

Android系統(tǒng)內(nèi)存分配,實(shí)際上是對堆的分配和釋放。

2.1.2內(nèi)存回收機(jī)制

年輕代、老年代、持久代。

年輕代

所有新生成的對象都放在年輕代。

年輕代分為一個(gè)Eden區(qū)和兩個(gè)Survivor區(qū)。

GC時(shí),當(dāng)Eden區(qū)滿時(shí),還存活的對象會(huì)被復(fù)制到其中一個(gè)Survivor區(qū)(A)。

當(dāng)這個(gè)Survivor區(qū)(A)也滿時(shí),就會(huì)被復(fù)制到另一個(gè)Survivor區(qū)(B)。

當(dāng)Survivor區(qū)(B)也滿時(shí),從第一個(gè)Survivor(B)復(fù)制過來并且還存活的對象,就會(huì)被復(fù)制到老年代。

老年代

在年輕代經(jīng)歷了N次垃圾回收仍然存活的到對象,就被放到老年代。

持久代

主要存放靜態(tài)文件,比如Java類,方法等。

持久代對垃圾回收沒有明顯影響。

如果持久代空間太小,可通過-XX:MaxPermSize =< N配置。

2.2內(nèi)存泄露場景

資源類的對象未關(guān)閉。

注冊系統(tǒng)事件未注銷:使用Sensor Manager等系統(tǒng)服務(wù),Context.getSystemService(int name)獲取系統(tǒng)服務(wù)。

類的靜態(tài)變量持有大數(shù)據(jù)對象:如,activity的靜態(tài)變量持有該activty的引用。

非靜態(tài)內(nèi)部類的靜態(tài)實(shí)例。

Handler造成內(nèi)存泄漏。

WebView。

匿名類:new AsyncTask,new Thead,TimerTask。這些匿名類對象結(jié)束之前一直持有對應(yīng)activity的引用,導(dǎo)致activity實(shí)例無法被回收,造成內(nèi)存泄漏。

2.3分析工具

Memory Monitor,Heap Viewer,Allocation Tracker,Memory Analyzer Tool,LeakCanary。

2.4優(yōu)化手段

2.4.1對象引用

根據(jù)實(shí)際需求,合理使用強(qiáng)引用,軟引用,弱引用,虛引用。

2.4.2減少不必要的內(nèi)存開銷

增加內(nèi)存復(fù)用:比如合理使用系統(tǒng)自帶的資源,視圖,圖片,對象池等的復(fù)用。

留意自動(dòng)裝箱。

2.4.3使用最優(yōu)數(shù)據(jù)類型

使用最優(yōu)數(shù)據(jù)類型,比如使用ArrayMap,避免使用枚舉類型,使用LruCache等。

2.4.5圖片內(nèi)存優(yōu)化

圖片壓縮,圖片緩存。

3.穩(wěn)定性優(yōu)化

3.1異常場景

Crash,ANR。

3.2分析工具

穩(wěn)定性主要依賴代碼優(yōu)化,邏輯實(shí)現(xiàn)的優(yōu)化來提升。所以從代碼層面來看,分析工具主要有:Android Lint,F(xiàn)indbugs,Checkstyle,PMD,F(xiàn)ireLine。

3.3優(yōu)化手段

3.3.1提高代碼質(zhì)量。
3.3.2代碼掃描。
3.3.3Crash監(jiān)控。
3.3.4Crash上報(bào)機(jī)制。

4.耗電優(yōu)化

4.1耗電后果

App耗電嚴(yán)重,會(huì)給用戶帶來非常差的體驗(yàn),導(dǎo)致用戶卸載應(yīng)用。

4.2優(yōu)化手段

4.2.1Battery Historian

這是Google出的Android系統(tǒng)電量分析工具。

4.2.2計(jì)算優(yōu)化

避免浮點(diǎn)運(yùn)算等等。

4.2.3避免WakeLock不當(dāng)使用。
4.2.4使用Job Schedule。

5.安裝包大小優(yōu)化

5.1優(yōu)化體積大小的原因

節(jié)省流量,提高用戶對App的好感度。

5.2優(yōu)化手段及工具

5.2.1代碼混淆

使用ProGuard工具進(jìn)行壓縮,優(yōu)化,混淆。ProGuard的原理:壓縮,優(yōu)化,混淆。

5.2.2資源優(yōu)化

使用Android Lint刪除冗余資源,使資源文件最小化。

5.2.3圖片優(yōu)化

使用AAPT,TinyPng壓縮圖片,使用webP圖片格式等。

5.2.4避免引入重復(fù)功能的庫

對比選擇最優(yōu)庫,不要引入多個(gè)類似功能的庫。如果有相關(guān)庫的源碼,可根據(jù)實(shí)際需求,抽取需要的代碼重新編譯庫,讓庫盡可能的小。

5.2.5插件化

可將功能模塊放服務(wù)器,需要用時(shí)再加載。

6.數(shù)據(jù)庫SQLite優(yōu)化

6.1優(yōu)化手段

6.1.1索引
概念:

索引是對數(shù)據(jù)庫表中一列或多列數(shù)據(jù)進(jìn)行排序的一種數(shù)據(jù)結(jié)構(gòu)??衫斫鉃橐粋€(gè)指向表中數(shù)據(jù)的指針,與一本書的目錄類似。

優(yōu)點(diǎn):

加快表中數(shù)據(jù)查詢速度。

缺點(diǎn):

創(chuàng)建索引本身也會(huì)造成資源開銷。

類別:

表索引: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)。

總結(jié):

合理使用索引,可加快數(shù)據(jù)庫表數(shù)據(jù)的查詢速率。

6.1.2事務(wù)
概念:

對數(shù)據(jù)庫原子性的操作。

優(yōu)點(diǎn):

為數(shù)據(jù)的整體性執(zhí)行帶來可靠安全性,為更新和刪除操作帶來很大優(yōu)化。

總結(jié):

保證數(shù)據(jù)的完整性,安全性,提高數(shù)據(jù)更新,刪除操作的效率。

6.1.3其他手段

盡量少用cursor.getColumnIndex()。

用StringBuilder(非線程安全)或StringBuffer(線程安全)來拼接字符串。

查詢時(shí),只返回需要的數(shù)據(jù)或結(jié)果。

cursor使用后要及時(shí)關(guān)閉。

7.網(wǎng)絡(luò)優(yōu)化

7.1原因

網(wǎng)絡(luò)優(yōu)化不好,造成用戶流量消耗大,耗電快,用戶等待時(shí)間長體驗(yàn)差等。

7.2工具

Network Monitor,Charles,F(xiàn)iddler,Stecho。

7.3優(yōu)化手段

7.3.1接口設(shè)計(jì)

API設(shè)計(jì)要合理。

使用GZIP壓縮。

選擇合適的數(shù)據(jù)格式:json,xml,protocol Buffer。

7.3.2圖片處理

圖片下載:

使用縮略圖。

使用WebP圖片。

根據(jù)設(shè)備規(guī)格,指定圖片尺寸請求圖片。

使用完善的合適的圖片加載框架:Glide,Picasso等。

圖片上傳:一般要支持?jǐn)帱c(diǎn)續(xù)傳。

7.3.3網(wǎng)絡(luò)緩存

適當(dāng)緩存,可讓App看起來更快。

使用DiskLruCache。

7.3.4打包網(wǎng)絡(luò)請求

網(wǎng)絡(luò)狀況好(如:WiFi狀態(tài)下),可一次異步發(fā)起多個(gè)業(yè)務(wù)模塊的數(shù)據(jù)請求。

7.3.5監(jiān)聽相關(guān)狀態(tài)變化

休眠狀態(tài)(即:熄屏狀態(tài)下),盡量不要發(fā)起網(wǎng)絡(luò)請求。

充電狀態(tài),可適當(dāng)做一些必要的網(wǎng)絡(luò)請求,但要控制頻率。

弱網(wǎng)狀態(tài)下,可壓縮和減少數(shù)據(jù)傳輸量;不要自動(dòng)加載圖片,用占位圖顯示;頁面視圖先顯示,網(wǎng)絡(luò)請求延遲提交。

7.3.6優(yōu)化網(wǎng)絡(luò)請求機(jī)制

劃分網(wǎng)絡(luò)請求的優(yōu)先級(jí),同一頁面,同一模塊,重要的數(shù)據(jù)優(yōu)先請求。

網(wǎng)絡(luò)差,減少請求量;網(wǎng)絡(luò)好,提高請求量。

合并網(wǎng)絡(luò)請求,減少請求次數(shù)。比如,本地埋點(diǎn)數(shù)據(jù),無需實(shí)時(shí)上報(bào),可先本地緩存,再根據(jù)上報(bào)策略,選擇合適時(shí)機(jī)一并上報(bào)。

7.3.8IP直連和HttpDns

IP直連,省去DNS解析時(shí)間。

使用HttpDns,防止運(yùn)營商域名劫持或跨網(wǎng)訪問問題。

7.3.9優(yōu)化請求頻率

使用本地緩存,讓App在離線狀態(tài)也能使用。

優(yōu)先使用緩存;當(dāng)沒有緩存或緩存國旗,再請求網(wǎng)絡(luò)數(shù)據(jù)。

App性能優(yōu)化,是一個(gè)持續(xù)地過程,需要我們不斷提高自己性能優(yōu)化的能力,才能提高App的性能,才能打造出"快,省,穩(wěn)"的極佳體驗(yàn)App。

加油~~


大家有好的建議和看法,都?xì)g迎在評(píng)論區(qū)留言,一起交流學(xué)習(xí),謝謝??。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容