本文目錄:
一泡态、性能測(cè)試
1.內(nèi)存消耗 2.CPU占用 3.幀率GPU 4.流量消耗 5.電量消耗
二、性能優(yōu)化
1.卡頓優(yōu)化 2.耗電優(yōu)化 3.安裝包大小優(yōu)化 4.內(nèi)存優(yōu)化 5.穩(wěn)定性優(yōu)化
一乙墙、性能測(cè)試
1焰雕、內(nèi)存消耗
1.1 使用Android Profiler
1.2 使用adb
輸入命令:adb shell dumpsys meminfo PackageName
1.3 使用Lint
Android Studio->Analyze->Inspect Code
1.4 使用MAT
1.5 使用Heap Snapshot
2淑玫、CPU占用
2.1 使用Android Profiler
3苟鸯、幀率GPU
3.1 使用“GPU呈現(xiàn)模式分析”中的“在adb shell dumpsys gfxinfo中”選項(xiàng)。
① 進(jìn)入Android設(shè)備的開發(fā)者選項(xiàng)疲扎,勾選“GPU呈現(xiàn)模式分析”中的“在adb shell dumpsys gfxinfo中”選項(xiàng)谭企。
② 在電腦的terminal中進(jìn)入<SDK目錄>下的platform-tools文件夾,輸入命令adb shell dumpsys gfxinfo 包名评肆,結(jié)果如圖所示
③ 參數(shù)說明
- Graphics info for pid 7821 [com.longsh1z.myapplication]
//表明當(dāng)前dump的為設(shè)置界面的幀信息债查,pid為7821
- Total frames rendered: 15
//本次dump搜集了105幀的信息
- Janky frames: 15 (100.00%)
//15幀中有15幀的耗時(shí)超過了16ms,卡頓概率為100.00%
- Number Missed Vsync: 3
//垂直同步失敗的幀
- Number High input latency: 7
//處理input時(shí)間超時(shí)的幀數(shù)
- Number Slow UI thread: 4
//因UI線程上的工作導(dǎo)致超時(shí)的幀數(shù)
- Number Slow bitmap uploads: 2
//因bitmap的加載耗時(shí)的幀數(shù)
- Number Slow issue draw commands: 8
//因繪制導(dǎo)致耗時(shí)的幀數(shù)
- HISTOGRAM: 5ms=0 6ms=0 7ms=0 ...
//直方圖數(shù)據(jù)瓜挽,表面耗時(shí)為0-5ms的幀數(shù)為0盹廷,耗時(shí)為5-6ms的幀數(shù)為0,同理類推久橙。
3.2 使用“GPU呈現(xiàn)模式分析”中的“在屏幕上顯示為條形圖”選項(xiàng)俄占。**
① 進(jìn)入Android設(shè)備的開發(fā)者選項(xiàng)管怠,勾選“GPU呈現(xiàn)模式分析”中的“在屏幕上顯示為條形圖”選項(xiàng)。
② 操作自己的APP缸榄,屏幕上即有相關(guān)顯示渤弛。
4、流量消耗
4.1 使用adb(Linux環(huán)境下)
獲取進(jìn)程ID指令
adb shell ps|grep packagename
獲取進(jìn)程ID流量
adb shell cat /proc/pid/net/dev
4.2 使用GT(隨身調(diào)甚带,騰訊MIG內(nèi)部)
5她肯、電量消耗
5.1 使用adb
輸入命令:
①adb shell dumpsys batterystats PackageName(Android 5.0后引入)
//獲取單個(gè)應(yīng)用的耗電量信息
②adb shell dumpsys battery
//獲取設(shè)備的是否充電,電量鹰贵,電壓等信息
(注:后續(xù)可以用battery-historian將輸出可視化)
二晴氨、性能優(yōu)化
1、卡頓優(yōu)化
1.1 原因
- Android系統(tǒng)每隔16ms會(huì)發(fā)出VSync信號(hào)碉输,觸發(fā)對(duì)UI的渲染籽前。所以如果每一幀的繪制時(shí)間過長(zhǎng)或者主線程太忙,導(dǎo)致VSync信號(hào)到來時(shí)數(shù)據(jù)還沒準(zhǔn)備好敷钾,那么兩幀的時(shí)間內(nèi)還是顯示的同一幀的內(nèi)容枝哄,就會(huì)給人卡頓的感覺。
- 舉個(gè)形象一點(diǎn)的例子阻荒,在我們上學(xué)的時(shí)候我們每天都要交作業(yè)挠锥,那么我們未能按時(shí)完成作業(yè)的原因有哪些呢?其實(shí)無外乎兩種:一種是作業(yè)太多财松,我們?cè)谝惶靸?nèi)完不成;另一種就是其他事情占用太多時(shí)間了纱控,要交作業(yè)的時(shí)候我們還沒能完成辆毡。
1.2 優(yōu)化方案
1.2.1 UI優(yōu)化:
- 盡量避免多層布局嵌套,使用RelativeLayout
- 在布局層級(jí)相同的情況下甜害,優(yōu)先用LinearLayout
- 將可復(fù)用的組件抽取出來并通過<include>標(biāo)簽使用
- 使用<merge>標(biāo)簽減少布局的嵌套層次
- 使用<ViewStub>標(biāo)簽加載一些不常用的布局
- 刪除控件中沒用的屬性
- 盡量避免過度繪制舶掖,比如背景經(jīng)常容易造成過度繪制。由于我們布局設(shè)置了背景尔店,同時(shí)用到的Material Design的主題會(huì)默認(rèn)給一個(gè)背景眨攘,這時(shí)候應(yīng)該把主題添加的背景去掉。
- 移除XML文件中非必須的背景嚣州。
1.2.2 啟動(dòng)優(yōu)化:
- 以大化小進(jìn)行分步加載鲫售,耗時(shí)操作異步加載,非必需的數(shù)據(jù)延時(shí)加載该肴。
1.2.3 刷新機(jī)制合理化
- 盡量減少刷新次數(shù)
- 盡量避免后臺(tái)有高CPU線程運(yùn)行
- 縮小刷新區(qū)域情竹。
2、耗電優(yōu)化
2.1 原因
在 Android 平臺(tái)上匀哄,由于應(yīng)用程序可以無限制地注冊(cè)系統(tǒng)事件(BroadcastReceiver)秦效,在這些事件中被不停地喚醒雏蛮,即使應(yīng)用已經(jīng)退到后臺(tái),做了很多毫無必要的事情阱州,卻導(dǎo)致電量消耗挑秉。因此,應(yīng)用開發(fā)者在實(shí)現(xiàn)需求的同時(shí)苔货,需要盡量減少電量的消耗犀概。
2.2 優(yōu)化方案
- 合理的使用wake_lock鎖。
- 使用jobScheduler2集中處理一些網(wǎng)絡(luò)請(qǐng)求蒲赂,有些不用很及時(shí)的處理可以放在充電的時(shí)候處理阱冶,比如圖片的處理,APP下載更新等滥嘴。
- 計(jì)算優(yōu)化木蹬,避開浮點(diǎn)運(yùn)算。
- 數(shù)據(jù)在網(wǎng)絡(luò)上傳輸時(shí)若皱,盡量壓縮數(shù)據(jù)后再傳輸镊叁。
- 使用效率高的數(shù)據(jù)格式和解析方法,建議用FlatBuffer序列化技術(shù)走触,這個(gè)比json效率高很多倍晦譬。
- 使用Wi-Fi傳輸數(shù)據(jù)時(shí),應(yīng)盡可能增大每個(gè)包的大谢ス恪(不超過MTU)并降低發(fā)包的頻率敛腌。
- 盡量在Wi-Fi環(huán)境下使用數(shù)據(jù)傳輸。
- 在蜂窩移動(dòng)網(wǎng)絡(luò)下惫皱,最好做到批量執(zhí)行網(wǎng)絡(luò)請(qǐng)求像樊,盡量避免頻繁的間隔網(wǎng)絡(luò)請(qǐng)求,盡量多地保持在Radio Standby狀態(tài)旅敷。
3生棍、安裝包大小優(yōu)化
3.1 原因
應(yīng)用的安裝包越大,用戶下載的門檻越高媳谁,特別是在移動(dòng)網(wǎng)絡(luò)情況下涂滴,所以減小安裝包大小可以讓更多的用戶愿意下載和體驗(yàn)產(chǎn)品。
3.2 優(yōu)化方案
3.2.1 代碼混淆優(yōu)化
- 使用ProGuard設(shè)置minifyEnabled 為true晴音。
3.2.2 res資源優(yōu)化
- 使用Android Lint刪除冗余資源柔纵。
- 盡量使用一套圖片資源,遇到一些圖片在不同分辨率手機(jī)上變化差異過大的情況時(shí)锤躁,再考慮在響應(yīng)文件夾下放入這個(gè)特定的圖片首量。
- 使用一套圖、一套布局、多套dimens.xml文件加缘,在使用最小資源的情況下鸭叙,解決多分辨率適配。
- 使用輕量級(jí)的第三方庫拣宏。
- 減少項(xiàng)目中的預(yù)置圖片沈贝,預(yù)置圖片改成有服務(wù)器下發(fā),盡可能的將程序與資源分離勋乾。
- 使用WebP格式的圖片宋下。
3.2.3 代碼優(yōu)化
- 實(shí)現(xiàn)功能模塊的邏輯簡(jiǎn)化。
- 移除無用的依賴庫辑莫。
3.2.4 lib資源優(yōu)化
- 一些模塊的插件化動(dòng)態(tài)添加学歧。
- so文件的剪裁和壓縮。
3.2.5 assets資源優(yōu)化
- 音頻文件最好使用有損壓縮的格式各吨,比如采用opus枝笨、mp3等格式,但是最好不要使用無損壓縮的音樂格式揭蜒。
4横浑、內(nèi)存優(yōu)化
4.1 原因
在 Android 系統(tǒng)中有個(gè)垃圾內(nèi)存回收機(jī)制,在虛擬機(jī)層自動(dòng)分配和釋放內(nèi)存屉更,因此不需要在代碼中分配和釋放某一塊內(nèi)存徙融,從應(yīng)用層面上不容易出現(xiàn)內(nèi)存泄漏和內(nèi)存溢出等問題,但是需要內(nèi)存管理瑰谜。Android 系統(tǒng)在內(nèi)存管理上有一個(gè) Generational Heap Memory 模型欺冀,內(nèi)存回收的大部分壓力不需要應(yīng)用層關(guān)心, Generational Heap Memory 有自己一套管理機(jī)制萨脑,當(dāng)內(nèi)存達(dá)到一個(gè)閾值時(shí)隐轩,系統(tǒng)會(huì)根據(jù)不同的規(guī)則自動(dòng)釋放系統(tǒng)認(rèn)為可以釋放的內(nèi)存,也正是因?yàn)?Android 程序把內(nèi)存控制的權(quán)力交給了 Generational Heap Memory砚哗,一旦出現(xiàn)內(nèi)存泄漏和溢出方面的問題龙助,排查錯(cuò)誤將會(huì)成為一項(xiàng)異常艱難的工作砰奕。除此之外蛛芥,部分 Android 應(yīng)用開發(fā)人員在開發(fā)過程中并沒有特別關(guān)注內(nèi)存的合理使用,也沒有在內(nèi)存方面做太多的優(yōu)化军援,當(dāng)應(yīng)用程序同時(shí)運(yùn)行越來越多的任務(wù)仅淑,加上越來越復(fù)雜的業(yè)務(wù)需求時(shí),完全依賴 Android 的內(nèi)存管理機(jī)制就會(huì)導(dǎo)致一系列性能問題逐漸呈現(xiàn)胸哥,對(duì)應(yīng)用的穩(wěn)定性和性能帶來不可忽視的影響涯竟,因此,解決內(nèi)存問題和合理優(yōu)化內(nèi)存是非常有必要的。
4.2 優(yōu)化方案
4.2.1 內(nèi)存泄漏優(yōu)化
- 單例模式中傳入的this來源于activity所引起的內(nèi)存泄漏庐船,可以使用context.getApplicationContext代替银酬。
- Handler引起的內(nèi)存泄漏。message會(huì)持有handler的引用筐钟,而非靜態(tài)內(nèi)部類的handler會(huì)持有外部類activity的引用揩瞪,這樣activity被銷毀了但是handler中還有message存在,activity的引用未能及時(shí)釋放從而造成內(nèi)存泄漏篓冲±钇疲可以將handler改為靜態(tài)內(nèi)部類,同時(shí)activity用弱引用壹将。
- AsyncTask或線程引起的內(nèi)存泄漏嗤攻,匿名內(nèi)部類AsyncTask或Thread會(huì)持有外部類activity的引用,activity被銷毀了诽俯,AsyncTask或者線程還未結(jié)束從而引起的內(nèi)存泄漏妇菱。可以將AsyncTask和Thread獨(dú)立出來或者使用靜態(tài)內(nèi)部類惊畏,同時(shí)activity用弱引用恶耽。
- 資源未及時(shí)關(guān)閉引起的內(nèi)存泄漏,需要及時(shí)關(guān)閉cursor颜启,廣播接收器偷俭、網(wǎng)絡(luò)連接等資源。
4.2.2 其他優(yōu)化
- 減少不必要的內(nèi)存開銷缰盏。注意自動(dòng)裝箱涌萤,增加內(nèi)存復(fù)用,比如有效利用系統(tǒng)自帶的資源口猜、視圖復(fù)用负溪、對(duì)象池、Bitmap對(duì)象的復(fù)用济炎。
- 使用最優(yōu)的數(shù)據(jù)類型川抡。比如針對(duì)數(shù)據(jù)類容器結(jié)構(gòu),可以使用ArrayMap數(shù)據(jù)結(jié)構(gòu)须尚,避免使用枚舉類型崖堤,使用緩存Lrucache等等。
- 圖片內(nèi)存優(yōu)化耐床∶茚#可以設(shè)置位圖規(guī)格,根據(jù)采樣因子做壓縮撩轰,用一些圖片緩存方式對(duì)圖片進(jìn)行管理等等胯甩。
5昧廷、穩(wěn)定性優(yōu)化
5.1 原因
Android 應(yīng)用的穩(wěn)定性定義很寬泛,影響穩(wěn)定性的原因很多偎箫,比如內(nèi)存使用不合理木柬、代碼異常場(chǎng)景考慮不周全、代碼邏輯不合理等淹办,都會(huì)對(duì)應(yīng)用的穩(wěn)定性造成影響弄诲。其中最常見的兩個(gè)場(chǎng)景是:Crash 和 ANR,這兩個(gè)錯(cuò)誤將會(huì)使得程序無法使用娇唯。
5.2 優(yōu)化方案
- 提高代碼質(zhì)量齐遵。比如開發(fā)期間的代碼審核,看些代碼設(shè)計(jì)邏輯塔插,業(yè)務(wù)合理性等梗摇。
- 代碼靜態(tài)掃描工具。常見工具有Android Lint、Findbugs、Checkstyle气堕、PMD等等。
- Crash監(jiān)控糜烹。把一些崩潰的信息,異常信息及時(shí)地記錄下來漱凝,以便后續(xù)分析解決疮蹦。
- Crash上傳機(jī)制。在Crash后茸炒,盡量先保存日志到本地愕乎,然后等下一次網(wǎng)絡(luò)正常時(shí)再上傳日志信息。