一.何為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í),謝謝??。