詳解安卓應(yīng)用性能測(cè)試方法以及Android SDK中輔助測(cè)試的工具使用
Android應(yīng)用測(cè)試點(diǎn)
Android前端APP的性能測(cè)試一般針對(duì)以下幾個(gè)方面:應(yīng)用啟動(dòng)時(shí)間;CPU的占用;內(nèi)存的占用;流量的耗用;電量的耗用;流暢度等。一般對(duì)App進(jìn)行性能測(cè)試都需要借助不同的工具完成,本章節(jié)會(huì)向讀者重點(diǎn)介紹針對(duì)不同的性能測(cè)試指標(biāo)該選用哪種工具以及工具的具體使用方法。
因?yàn)锳ndroid 手機(jī)是Linux內(nèi)核,最簡(jiǎn)單的命令就是使用top命令查看手機(jī)的 cpu、內(nèi)存的占用情況。
具體操作:
PC中成功安裝Android SDK
手機(jī)成功連接PC
Android手機(jī) ->設(shè)置 ->開發(fā)者選項(xiàng)->USB調(diào)試(打上勾)
在cmd窗口中輸入 adb shell ,進(jìn)入adb shell命令模式
方法1:輸入top 顯示如下:

具體參數(shù)含義如下:
CPU占用率:
- User 用戶進(jìn)程
- System 系統(tǒng)進(jìn)程
- IOW
- IO等待時(shí)間
- IRQ 硬中斷時(shí)間
- CPU使用情況(指一個(gè)最小時(shí)間片內(nèi)所占時(shí)間,單位jiffies。或者指所占進(jìn)程數(shù)):
- User 處于用戶態(tài)的運(yùn)行時(shí)間,不包含優(yōu)先值為負(fù)進(jìn)程
- Nice 優(yōu)先值為負(fù)的進(jìn)程所占用的CPU時(shí)間
- Sys 處于核心態(tài)的運(yùn)行時(shí)間
- Idle 除IO等待時(shí)間以外的其它等待時(shí)間
- IOW
- IO等待時(shí)間
- IRQ 硬中斷時(shí)間
- SIRQ 軟中斷時(shí)間
進(jìn)程屬性:
- PID 進(jìn)程在系統(tǒng)中的ID
- CPU% 當(dāng)前瞬時(shí)所以使用CPU占用率
- S 進(jìn)程的狀態(tài),其中S表示休眠,R表示正在運(yùn)行,Z表示僵死狀態(tài),N表示該進(jìn)程優(yōu)先值是負(fù)數(shù)。
- #THR 程序當(dāng)前所用的線程數(shù)
內(nèi)存:
- VSS
- Virtual Set Size 虛擬耗用內(nèi)存(包含共享庫(kù)占用的內(nèi)存)
- RSS
- Resident Set Size 實(shí)際使用物理內(nèi)存(包含共享庫(kù)占用的內(nèi)存)
- UID 運(yùn)行當(dāng)前進(jìn)程的用戶id
- Name 程序名稱system_server
- 備注:內(nèi)存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS
- PSS Proportional Set Size實(shí)際使用的物理內(nèi)存(比例分配共享庫(kù)占用的內(nèi)存)
- USS Unique Set Size進(jìn)程獨(dú)自占用的物理內(nèi)存(不包含共享庫(kù)占用的內(nèi)存)
應(yīng)用啟動(dòng)時(shí)間測(cè)試
adb shell am start -W –n /
am命令的詳細(xì)使用方法請(qǐng)參考章節(jié)am與pm命令
注意:?jiǎn)?dòng)時(shí)間需要區(qū)分首次啟動(dòng)和非首次啟動(dòng)
耗電測(cè)試
請(qǐng)參考文章Android App 耗電的測(cè)試方法
流暢度和網(wǎng)絡(luò)消耗測(cè)試
請(qǐng)參考文章詳解移動(dòng)應(yīng)用測(cè)試神器PerfDog
接下來我來介紹幾款A(yù)ndroid sdk中自帶的,可以幫助我們搞定性能問題的工具!
Dumps命令
Dumpsys命令默認(rèn)打印出當(dāng)前系統(tǒng)所有服務(wù)信息
使用命令dumpsys | grep "DUMP OF SERVICE" 可以查看的內(nèi)容包括:
- DUMP OF SERVICE DockObserver:
- DUMP OF SERVICE SurfaceFlinger:
- DUMP OF SERVICE accessibility:
- DUMP OF SERVICE account:
- DUMP OF SERVICE activity:
- DUMP OF SERVICE alarm:
- DUMP OF SERVICE android.security.keystore:
- DUMP OF SERVICEandroid.service.gatekeeper.IGateKeeperService:
- DUMP OF SERVICE appops:
- DUMP OF SERVICE appwidget:
- DUMP OF SERVICE assetatlas:
- DUMP OF SERVICE audio:
- DUMP OF SERVICE backup:
- DUMP OF SERVICE battery:
- DUMP OF SERVICE batteryproperties:
- DUMP OF SERVICE batterystats:
- DUMP OF SERVICE bluetooth_manager:
- DUMP OF SERVICE carrier_config:
- DUMP OF SERVICE clipboard:
- DUMP OF SERVICE commontime_management:
- DUMP OF SERVICE connectivity:
- DUMP OF SERVICE consumer_ir:
- DUMP OF SERVICE content:
- DUMP OF SERVICE country_detector:
- DUMP OF SERVICE cpuinfo:
- DUMP OF SERVICE dbinfo:
- DUMP OF SERVICE device_policy:
- DUMP OF SERVICE deviceidle:
- DUMP OF SERVICE devicestoragemonitor:
- DUMP OF SERVICE diskstats:
- DUMP OF SERVICE display:
- DUMP OF SERVICE display.qservice:
- DUMP OF SERVICE dreams:
- DUMP OF SERVICE drm.drmManager:
- DUMP OF SERVICE dropbox:
- DUMP OF SERVICE ethernet:
- DUMP OF SERVICE fingerprint:
- DUMP OF SERVICE gfxinfo:
- DUMP OF SERVICE graphicsstats:
- DUMP OF SERVICE imms:
- DUMP OF SERVICE input:
- DUMP OF SERVICE input_method:
- DUMP OF SERVICE iphonesubinfo:
- DUMP OF SERVICE isms:
- DUMP OF SERVICE isub:
- DUMP OF SERVICE jobscheduler:
- DUMP OF SERVICE launcherapps:
- DUMP OF SERVICE location:
- DUMP OF SERVICE lock_settings:
- DUMP OF SERVICE media.audio_flinger:
- DUMP OF SERVICE media.audio_policy:
- DUMP OF SERVICE media.camera:
- DUMP OF SERVICE media.camera.proxy:
- DUMP OF SERVICE media.player:
- DUMP OF SERVICE media.radio:
- DUMP OF SERVICE media.resource_manager:
- DUMP OF SERVICE media.sound_trigger_hw:
- DUMP OF SERVICE media_projection:
- DUMP OF SERVICE media_router:
- DUMP OF SERVICE media_session:
- DUMP OF SERVICE meminfo:
- DUMP OF SERVICE midi:
- DUMP OF SERVICE mount:
- DUMP OF SERVICE netpolicy:
- DUMP OF SERVICE netstats:
- DUMP OF SERVICE network_management:
- DUMP OF SERVICE network_score:
- DUMP OF SERVICE nfc:
- DUMP OF SERVICE notification:
- DUMP OF SERVICE package:
- DUMP OF SERVICE permission:
- DUMP OF SERVICE persistent_data_block:
- DUMP OF SERVICE phone:
- DUMP OF SERVICE power:
- DUMP OF SERVICE print:
- DUMP OF SERVICE processinfo:
- DUMP OF SERVICE procstats:
- DUMP OF SERVICE restrictions:
- DUMP OF SERVICE rttmanager:
- DUMP OF SERVICE samplingprofiler:
- DUMP OF SERVICE scheduling_policy:
- DUMP OF SERVICE search:
- DUMP OF SERVICE sensorservice:
- DUMP OF SERVICE serial:
- DUMP OF SERVICE servicediscovery:
- DUMP OF SERVICE simphonebook:
- DUMP OF SERVICE sip:
- DUMP OF SERVICE statusbar:
- DUMP OF SERVICE telecom:
- DUMP OF SERVICE telephony.registry:
- DUMP OF SERVICE textservices:
- DUMP OF SERVICE trust:
- DUMP OF SERVICE uimode:
- DUMP OF SERVICE updatelock:
- DUMP OF SERVICE usagestats:
- DUMP OF SERVICE usb:
- DUMP OF SERVICE user:
- DUMP OF SERVICE vibrator:
- DUMP OF SERVICE voiceinteraction:
- DUMP OF SERVICE wallpaper:
- DUMP OF SERVICE webviewupdate:
- DUMP OF SERVICE wifi:
- DUMP OF SERVICE wifip2p:
- DUMP OF SERVICE wifiscanner:
- DUMP OF SERVICE window:
關(guān)鍵信息顯示:
activity:顯示所有的activities的信息
cpuinfo:顯示CPU信息
window:顯示鍵盤,窗口和它們的關(guān)系
wifi:顯示wifi信息
batteryinfo $package_name:電量信息及CPU 使用時(shí)長(zhǎng)
package packagename:獲取安裝包信息
usagestats:每個(gè)界面啟動(dòng)的時(shí)間
statusbar:顯示狀態(tài)欄相關(guān)的信息
meminfo:內(nèi)存信息(meminfo $package_name or $pid使用程序的包名或者進(jìn)程id顯示內(nèi)存信息)
diskstats:磁盤相關(guān)信息
battery:電池信息
alarm:顯示Alarm信息
例如,輸出某個(gè)應(yīng)用的cpu信息,可以使用命令
dumpsys cpuinfo |your app package
am命令
am全稱activity manager,使用am可以模擬各種系統(tǒng)的行為,例如去啟動(dòng)一個(gè)activity,強(qiáng)制停止進(jìn)程,發(fā)送廣播進(jìn)程,修改設(shè)備屏幕屬性等等。
pm命令
pm全稱package manager,你能使用pm命令去模擬android行為或者查詢?cè)O(shè)備上的應(yīng)用等等。
GPU呈現(xiàn)模式分析
GPU:Graphic Processing Unit (圖形處理器),主要反映應(yīng)用的卡頓現(xiàn)象。
IOS與Android流暢與否的比較,主要是以下三個(gè)原因:
速度曲線
當(dāng)滑動(dòng)界面然后松手,這時(shí)界面會(huì)繼續(xù)滑動(dòng),然后速度減小,直到速度為0時(shí)停止。iOS下速度減小的這個(gè)過程比較慢,尤其是快要停的時(shí)候是慢慢停的,視覺上有種很順滑的感覺;Android下則從松手到停要快很多,相比之下有種戛然而止的感覺。
從數(shù)據(jù)/技術(shù)角度來看這個(gè)事情,我們滑動(dòng)界面的最終目的不是為了“動(dòng)”,而是為了“停”,因此只要平滑地到達(dá)目的地,似乎越快完成這個(gè)過程越好,所以Android的選擇是理所當(dāng)然的。但事實(shí)是,大家普遍更喜歡iOS的方式,這樣做顯得更順滑、更優(yōu)雅。
幀率
幀率:FPS是圖像領(lǐng)域中的定義,是指畫面每秒傳輸幀數(shù),通俗來講就是指動(dòng)畫或視頻的畫面數(shù)。30FPS是一般錄像的常用幀數(shù),30FPS在快速動(dòng)作的時(shí)候會(huì)感覺不流暢。60FPS是一般游戲的常用幀數(shù)。
絕大部分時(shí)間兩者(Android和IOS)都能保持60FPS左右的滿幀率。但都會(huì)有偶爾的掉幀。并且Android上要比IOS上嚴(yán)重很多。掉幀導(dǎo)致卡頓,用戶必然會(huì)感覺到掉幀那一刻的不流暢。
觸摸響應(yīng)速度
從手指碰到觸摸屏,到屏幕上顯示處理這次觸摸產(chǎn)生的畫面,是需要時(shí)間的。時(shí)間越短感覺越跟手。在軟件系統(tǒng)層面,Android的顯示機(jī)制是app-->SurfaceFlinger-->Display,這比傳統(tǒng)的app-->Display多了一步,主要基于這個(gè)原因,畫面最終輸出到屏幕要比傳統(tǒng)的方式慢一幀(16.7ms)。
綜合分析:
第1點(diǎn)造成的影響最大,恰恰卻是與技術(shù)/設(shè)備無關(guān)的。如果Android app或者Android系統(tǒng)要改變,很容易就可以調(diào)得跟IOS一模一樣。但正是由于這是產(chǎn)品形態(tài)上的差別而不是純粹技術(shù)上的優(yōu)劣,反倒成了Android最不太可能改變的。
第2點(diǎn)的影響其次,當(dāng)然是指在目前這個(gè)大部分時(shí)候都能滿幀的情況下。這方面是Android從早期到現(xiàn)在進(jìn)步最明顯的方面,使用了很多方法來優(yōu)化幀率。但就算現(xiàn)在Android進(jìn)化了很多,硬件性能也進(jìn)化了很多,卻仍舊不可能徹底消滅掉幀的情況。
第3點(diǎn)通俗的講就是跟手性,跟手性的重要性不言而喻,但現(xiàn)在的差別比較細(xì)微。
Debug是否掉幀
前提條件:android系統(tǒng)4.0+
“開發(fā)者選項(xiàng)”->“GPU呈現(xiàn)模式分析”->“在屏幕上顯示為條形圖”,如下圖所示:
屏幕上有條綠色線(基準(zhǔn)線)大概是16ms,如果超過這條線則很有可能掉幀了

藍(lán)色代表測(cè)量繪制Display List的時(shí)間
紅色代表OpenGL渲染Display List所需要的時(shí)間
黃色代表CPU等待GPU處理的時(shí)間
過渡繪制
過度繪制指在屏幕的一個(gè)像素上繪制多次,我們對(duì)于UI性能的優(yōu)化還可以通過開發(fā)者選項(xiàng)中的GPU過度繪制工具來進(jìn)行分析。在設(shè)置->開發(fā)者選項(xiàng)->調(diào)試GPU過度繪制(不同設(shè)備可能位置或者叫法不同)中打開調(diào)試后可以看見如下圖2(對(duì)settings當(dāng)前界面過度繪制進(jìn)行分析):

顏色的含義:

Device Monitor
Device Monitor是一個(gè)用來給Android 程序進(jìn)行調(diào)試和分析的工具
包括:
- DDMS
- Tracerfor OpenGL ES
- HierarchyViewer
- Traceview
啟動(dòng)方式
Cmd窗口中 進(jìn)入sdk目錄中的\tools
輸入: monitor
前提條件:手機(jī)要root,否則好多功能用不了
Uiautomatorviewer
uiautomatorviewer 是一個(gè)圖形界面工具來掃描和分析應(yīng)用的UI控件。uiautomatorviewer通過ADB向設(shè)備側(cè)發(fā)送一個(gè)dump命令,下載一個(gè)包含當(dāng)前界面控件布局信息的xml文件。
Dump view hierarchy for ui automator

Traceview
Traceview是android平臺(tái)配備的一個(gè)很好的性能分析工具,堪比java的性能調(diào)優(yōu)工具visualvm線程視圖,可以方便的查看線程的執(zhí)行情況,某個(gè)方法執(zhí)行時(shí)間、調(diào)用次數(shù)、在總體中的占比等,從而定位性能點(diǎn)。
啟動(dòng):點(diǎn)擊下圖中的Start method Profiling

如下圖所示:

a.Incl表示將所有子函數(shù)耗時(shí)也計(jì)算在內(nèi),Excl則表示不包括子函數(shù)的調(diào)用時(shí)間。對(duì)比可以確定耗時(shí)操作發(fā)生是自身還是子函數(shù)中。
b.Cpu Time表示占用cpu執(zhí)行的時(shí)間,Real Time包括Cpu
Time以及等待、切換的時(shí)間等,所以一般都大于Cpu Time。對(duì)比可以判斷耗時(shí)操作是否在cpu執(zhí)行段內(nèi)。
c. 上面四個(gè)指標(biāo)對(duì)應(yīng)的%表示函數(shù)在總時(shí)間的占比。方便查看某個(gè)函數(shù)的時(shí)間占比。
d.Calls+RecurCalls/Total表示被外部調(diào)用次數(shù)+遞歸次數(shù)/總次數(shù)??梢圆榭凑{(diào)用次數(shù)是否符合自己預(yù)期。
e.Cpu Time/Call, Real Time/Call表示總的Cpu Time及Real Time與總調(diào)用次數(shù)的比例。查看每次調(diào)用的耗時(shí),一般可通過簡(jiǎn)單此項(xiàng)確定每個(gè)函數(shù)的性能。點(diǎn)擊Devices Tab中的Start Method Profiling 按鈕,需要停止時(shí)再次點(diǎn)擊該按鈕即可。
DDMS
概念:DDMS 的全稱是Dalvik Debug Monitor Service,它為我們提供例如:為測(cè)試設(shè)備截屏,針對(duì)特定的進(jìn)程查看正在運(yùn)行的線程以及堆信息、Logcat、廣播狀態(tài)信息、模擬電話呼叫、接收SMS、虛擬地理坐標(biāo)等等。DDMS將搭建起IDE與測(cè)試終端(Emulator或者connected device)的鏈接,它們應(yīng)用各自獨(dú)立的端口監(jiān)聽調(diào)試器的信息,DDMS可以實(shí)時(shí)監(jiān)測(cè)到測(cè)試終端的連接情況。當(dāng)有新的測(cè)試終端連接后,DDMS將捕捉到終端的ID,并通過adb建立調(diào)試器,從而實(shí)現(xiàn)發(fā)送指令到測(cè)試終端的目的。
在monitor中啟動(dòng)DDMS ,打開\Sdk\tools\monitor.bat,如下圖所示:
LogCat
logcat是Android中一個(gè)命令行工具,可以用于得到程序的log信息
Android日志信息都有一個(gè)標(biāo)簽和它的優(yōu)先級(jí).
日志的標(biāo)簽是系統(tǒng)部件原始信息的一個(gè)簡(jiǎn)要的標(biāo)志。(比如:“View”就 是查看系統(tǒng)的標(biāo)簽)
下列優(yōu)先級(jí)是按照從低到高順序排列的:
- V —Verbose (lowest priority)
- D —Debug
- I —Info
- W —Warning
- E —Error
- F —Fatal
- S —Silent (highest priority, on which nothing is ever printed)
Thread
查看進(jìn)程包含的線程信息

Heap
查看進(jìn)程使用的堆情況
點(diǎn)擊GC可以進(jìn)行對(duì)象回收;
判斷內(nèi)存泄露:一般情況下,在data object行的“Total Size”這個(gè)值得大小決定了是否會(huì)有內(nèi)存泄漏。
a) 不斷的操作當(dāng)前應(yīng)用,同時(shí)注意觀察data
object的Total Size值;
b) 正常情況下Total Size值都會(huì)穩(wěn)定在一個(gè)有限的范圍內(nèi),也就是說由于程序中的的代碼良好,沒有造成對(duì)象不被垃圾回收的情況,所以說雖然我們不斷的操作會(huì)不斷的生成很多對(duì)象,而在虛擬機(jī)不斷的進(jìn)行GC的過程中,這些對(duì)象都被回收了,內(nèi)存占用量會(huì)回落到一個(gè)穩(wěn)定的水平;
c) 反之如果代碼中存在沒有釋放對(duì)象引用的情況,則data
object的Total Size值在每次GC后不會(huì)有明顯的回落,隨著操作次數(shù)的增多Total Size的值會(huì)越來越大,
直到到達(dá)一個(gè)上限后導(dǎo)致進(jìn)程被殺掉。
參數(shù)含義:
1)Data Object:java object.
2)Class Object:object of type Class, e.g. what you'd get fromjava.lang.String.class or myObject.getClass( ).
3)1,2,4,8-byte array:Number of bytes per entry.
1-byte array: byte, boolean
2-byte array: char, short
4-byte array: float, int
8-byte array: double, long
4)non-Java object:A non-Java Object is a piece of memory that isn't actuallyaccessible from code written in Java. Essentially it's a blob of stuff that gotstuck on the virtual heap but has no meaning to interpreted code. Shouldn't bemuch of that.
分析內(nèi)存是否泄露:
通過mat 打開com.android.browser.hprof,分析內(nèi)存
在使用mat前必須轉(zhuǎn)化\tools\hprof-conv input.hprofoutput.hprof
File Explorer
查看Android系統(tǒng)的目錄文件,常用目錄和文件說明如下:
1、/mnt 掛載點(diǎn)目錄
2、/etc 系統(tǒng)主要配置文件
3、/system Android系統(tǒng)文件
4、/sys Linux 內(nèi)核文件
5、/proc 運(yùn)行時(shí)文件
6、/init.rc 啟動(dòng)腳本
7、/default.prop 系統(tǒng)屬性配置文件
8、/data 用戶程序目錄
9、/dev 存放與設(shè)備(包括外設(shè))有關(guān)的文件(unix和linux系統(tǒng)均把設(shè)備當(dāng)成文件)
AllocationTracker
查看線程中對(duì)象被分配的內(nèi)存情況

Systrace
Systrace是Android4.1中新增的性能數(shù)據(jù)采樣和分析工具。它可幫助開發(fā)者收集Android關(guān)鍵子系統(tǒng)(如surfaceflinger、WindowManagerService等Framework部分關(guān)鍵模塊、服務(wù))的運(yùn)行信息,從而幫助開發(fā)者更直觀的分析系統(tǒng)瓶頸,改進(jìn)性能。 注意:手機(jī)的內(nèi)核一定要支持trace(可以查看是否存在/sys/kernel/debug/tracing 這個(gè)目錄),
Systrace的功能包括跟蹤系統(tǒng)的I/O操作、內(nèi)核工作隊(duì)列、CPU負(fù)載以及Android各個(gè)子系統(tǒng)的運(yùn)行狀況等。在Android平臺(tái)中,它主要由3部分組成:
內(nèi)核部分:Systrace利用了Linux Kernel中的ftrace功能。所以,如果要使用Systrace的話,必須開啟kernel中和ftrace相關(guān)的模塊。
數(shù)據(jù)采集部分:Android定義了一個(gè)Trace類。應(yīng)用程序可利用該類把統(tǒng)計(jì)信息輸出給ftrace。同時(shí),Android還有一個(gè)atrace程序,它可以從ftrace中讀取統(tǒng)計(jì)信息然后交給數(shù)據(jù)分析工具來處理。
數(shù)據(jù)分析工具:Android提供一個(gè)systrace.py(python腳本文件,位于Android SDK目錄
/tools/platform-tools/systrace中)用來配置數(shù)據(jù)采集的方式(如采集數(shù)據(jù)的標(biāo)簽、輸出文件名等)和收集 ftrace統(tǒng)計(jì)數(shù)據(jù)并生成一個(gè)結(jié)果網(wǎng)頁文件供用戶查看。
從本質(zhì)上說,Systrace是對(duì)Linux Kernel中ftrace的封裝(ftrace 的作用是幫助開發(fā)人員了解 Linux 內(nèi)核的運(yùn)行時(shí)行為,以便進(jìn)行故障調(diào)試或性能分析。)。應(yīng)用進(jìn)程需要利用Android提供的Trace類來使用Systrace。
點(diǎn)擊下圖中的Capture SystemWide trace

可以設(shè)置抓取的系統(tǒng)參數(shù)如下:
備注:trace.html需要使用google chrome瀏覽器才能打開分析