Android壓力測試快速入門教程(圖解)——Monkey工具

文章目錄:html

1、Monkey簡介java

2、Monkey的基本用法android

3、Monkey測試示例圖解程序員

4、Monkey命令參數介紹shell

5、Monkey log分析windows

 

 

1、Monkey簡介網絡

Monkey:Android中的一命令行工具,壓力測試軟件穩定性和健壯性 併發

特色: 1.測試對象爲程序包,有必定侷限性 2.僞隨機事件,不能自定義 3.可對事件數量、類型、頻率設置app

 

如下內容來自ide

猴子的來源:至於Monkey的名字是有何而來的呢?這個沒有去怎麼考究,Monkey這個工具就是一個調皮的猴子,在App中亂按、亂摸、亂滾、亂跳。Monkey測試是Android平臺下自動化測試的一種快速有效的手段,經過Monkey工具能夠模擬用戶觸摸屏幕、滑動軌跡球、按鍵等操做來對模擬器或者手機設備上的軟件進行壓力測試,檢測該軟件的穩定性、健壯性。它的原理是向系統發送僞隨機的用戶事件流(如按鍵輸入、觸摸輸入、手勢輸入等),實現對正在開發的應用程序進行壓力測試。

   注:MonkeyRunner官方文檔的網址

    http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html

 

 

2、Monkey的基本用法

    基本語法以下:

    $ adb shell monkey [options]

    若是不指定optionsMonkey將以無反饋模式啓動,並把事件任意發送到安裝在目標環境中的所有包。下面是一個更爲典型的命令行示例,它啓動指定的應用程序,並向其發送1000個僞隨機事件:

    $ adb shell monkey -p your.package.name -v number

    $ monkey -ppackage的意思)  指定文件名 -v(測試的次數和頻率) number(次數)

 

3、Monkey測試示例圖解

 經過簡單的測試示例,初步瞭解並掌握Monkey測試的步驟。注意,這裏主要是使用adb命令進行安裝和相關操做。測試的具體參考步驟以下:

   (1)首先,先準備了一個測試用的應用程序(apk文件)。爲了測試,這裏選擇了一個格瓦拉手機購票App進行測試。下載地址爲: http://www.gewara.com/mobile/mobileMovie.xhtml

   下載好後,獲得下圖所示的apk文件。

 

   (2)將apk文件複製到android sdk對應platform-tools的目錄下。例如,筆者的sdk路徑爲 D:\android\android-sdk-windows\platform-tools。如圖所示

  

   (3)進行apk文件的安裝(安裝的前提是,已經啓動並能夠檢測模擬器):有安裝91助手或者豌豆的用戶能夠直接雙擊apk文件進行安裝;也可使用android下的adb命令進行安裝(以下圖所示,Success表示安裝成功)。

adb命令下安裝apk文件的命令爲:adb install 文件名.apk

  

(4)安裝好後,會在模擬器上看到應用程序的啓動圖標

   

   (5)安裝好apk文件後,須要知道應用程序主Activity(第一個啓動的Activity)所在的包名。

方法(獲取頂級包名的方法):在C盤根目錄新建log.txt,接着輸入cmd啓動控制檯,在控制檯中輸入:adb logcat>C:/log.txt,

而後點擊模擬器已經安裝好的APK圖標一下,而後打開控制檯,點擊ctrl+C;

接着找到log.txt文件,打開文件,按下快捷鍵CTRL+F在文件中查找「I/Activity」關鍵字,找到有「Displayed 」關鍵字的後面就是包名。

(知道了apk的包名,咱們也能夠利用adb命令進行應用程序的卸載;卸載apk文件的命令爲:adb uninstall 包名)

 

(6)這裏是最關鍵的一步,使用moneky命令進行自動化壓力測試。

  adb shell monkey [options] <event-count> 

命令爲:#monkey -p com.gewara -v 1000(參數說明:-p後跟着軟件所在包名,-v後跟測試的次數)。這裏對該軟件進行1000次的自動化測試,幾分鐘內便可以完成測試。如圖所示

 

  

 

  (7)測試完畢,發現程序出錯了。程序出錯,代表該軟件的穩定性和健壯性還有待提升。

  這時,能夠打開Lotcat查看出錯信息。如圖所示

     

 

4、Monkey命令參數介紹

 

要獲取Monkey命令自帶的簡單幫助,在CMD中執行命令:

 

adb shell monkey –help

 

 

1) 參數:  -p

參數-p用於約束限制,用此參數指定一個或多個包(Package,即App)。指定包以後,Monkey將只容許系統啓動指定的APP。若是不指定包,Monkey將容許系統啓動設備中的全部APP。

* 指定一個包: adb shell monkey -p com.htc.Weather  100

說明:com.htc.Weather爲包名,100是事件計數(即讓Monkey程序模擬100次隨機用戶事件)。

* 指定多個包:adb shell monkey -p com.htc.Weather –p com.htc.pdfreader  -p com.htc.photo.widgets 100

* 不指定包:adb shell monkey 100

 說明:Monkey隨機啓動APP併發送100個隨機事件。

* 要查看設備中全部的包,在CMD窗口中執行如下命令:

  >adb shell

  #cd data/data

  #ls

  

2) 參數:  -v

用於指定反饋信息級別(信息級別就是日誌的詳細程度),總共分3個級別,分別對應的參數以下表所示:

日誌級別 Level 0 

示例 adb shell monkey -p com.htc.Weather –v 100

說明 缺省值,僅提供啓動提示、測試完成和最終結果等少許信息

 

日誌級別 Level 1

示例 adb shell monkey -p com.htc.Weather –v -v 100

說明  提供較爲詳細的日誌,包括每一個發送到Activity的事件信息

 

日誌級別 Level 2

示例 adb shell monkey -p com.htc.Weather –v -v –v 100

說明  最詳細的日誌,包括了測試中選中/未選中的Activity信息

 

3)參數:  -s

用於指定僞隨機數生成器的seed值,若是seed相同,則兩次Monkey測試所產生的事件序列也相同的。

* 示例:

 Monkey測試1:adb shell monkey -p com.htc.Weather –s 10 100

   Monkey 測試2:adb shell monkey -p com.htc.Weather –s 10 100

   兩次測試的效果是相同的,由於模擬的用戶操做序列(每次操做按照必定的前後順序所組成的一系列操做,即一個序列)是同樣的。操做序列雖然是隨機生成的,可是隻要咱們指定了相同的Seed值,就能夠保證兩次測試產生的隨機操做序列是徹底相同的,因此這個操做序列僞隨機的;

 

4) 參數:  --throttle <毫秒>

用於指定用戶操做(即事件)間的時延,單位是毫秒;

* 示例:adb shell monkey -p com.htc.Weather –throttle 3000 100

  

5) 參數:  --ignore-crashes

用於指定當應用程序崩潰時(Force & Close錯誤),Monkey是否中止運行。若是使用此參數,即便應用程序崩潰,Monkey依然會發送事件,直到事件計數完成。

* 示例1:adb shell monkey -p com.htc.Weather --ignore-crashes 1000

  測試過程當中即便Weather程序崩潰,Monkey依然會繼續發送事件直到事件數目達到1000爲止;

* 示例2:adb shell monkey -p com.htc.Weather 1000

  測試過程當中,若是Weather程序崩潰,Monkey將會中止運行。

 

 

6) 參數:  --ignore-timeouts

用於指定當應用程序發生ANR(Application No Responding)錯誤時,Monkey是否中止運行。若是使用此參數,即便應用程序發生ANR錯誤,Monkey依然會發送事件,直到事件計數完成。

 

7) 參數:  --ignore-security-exceptions

用於指定當應用程序發生許可錯誤時(如證書許可,網絡許可等),Monkey是否中止運行。若是使用此參數,即便應用程序發生許可錯誤,

Monkey依然會發送事件,直到事件計數完成。

 

8) 參數:  --kill-process-after-error

用於指定當應用程序發生錯誤時,是否中止其運行。若是指定此參數,當應用程序發生錯誤時,應用程序中止運行並保持在當前狀態(注意:應用程序僅是靜止在發生錯誤時的狀態,系統並不會結束該應用程序的進程)。

 

9) 參數:  --monitor-native-crashes

用於指定是否監視並報告應用程序發生崩潰的本地代碼。

 

10) 參數:  --pct-{+事件類別} {+事件類別百分比}

用於指定每種類別事件的數目百分比(在Monkey事件序列中,該類事件數目佔總事件數目的百分比)

 參數:使用說明:

示例:--pct-touch {+百分比}

調整觸摸事件的百分比(觸摸事件是一個down-up事件,它發生在屏幕上的某單一位置)

adb shell monkey -p com.htc.Weather --pct-touch 10 1000

 

--pct-motion {+百分比}

調整動做事件的百分比(動做事件由屏幕上某處的一個down事件、一系列的僞隨機事件和一個up事件組成)

adb shell monkey -p com.htc.Weather --pct-motion 20 1000

 

--pct-trackball {+百分比}

調整軌跡事件的百分比(軌跡事件由一個或幾個隨機的移動組成,有時還伴隨有點擊)

adb shell monkey -p com.htc.Weather --pct-trackball 30 1000

 

--pct-nav {+百分比}

 調整「基本」導航事件的百分比(導航事件由來自方向輸入設備的up/down/left/right組成)

adb shell monkey -p com.htc.Weather --pct-nav 40 1000

 

--pct-majornav {+百分比}

調整「主要」導航事件的百分比(這些導航事件一般引起圖形界面中的動做,如:5-way鍵盤的中間按鍵、回退按鍵、菜單按鍵)

adb shell monkey -p com.htc.Weather --pct-majornav 50 1000

 

--pct-syskeys {+百分比}

調整「系統」按鍵事件的百分比(這些按鍵一般被保留,由系統使用,如Home、Back、Start Call、End Call及音量控制鍵)

adb shell monkey -p com.htc.Weather --pct-syskeys 60 1000

 

--pct-appswitch {+百分比}

調整啓動Activity的百分比。在隨機間隔裏,Monkey將執行一個startActivity()調用,做爲最大程度覆蓋包中所有Activity的一種方法

adb shell monkey -p com.htc.Weather --pct-appswitch 70 1000

 

--pct-anyevent {+百分比}

調整其它類型事件的百分比。它包羅了全部其它類型的事件,如:按鍵、其它不經常使用的設備按鈕、等等

adb shell monkey -p com.htc.Weather

 

--pct -anyevent 100 1000* 指定多個類型事件的百分比:

adb shell monkey -p com.htc.Weather --pct-anyevent 50 --pct-appswitch 50 1000

注意:各事件類型的百分比總數不能超過100%;

 

 

測試語句如:adb -s emulator-5556 shell monkey -p 包名 -v 10000

adb -s emulator-5556 shell monkey -p com.soft0754.android -vvv 10000 > C:/log.txt

-v 爲 verbose的縮寫,就是詳細輸出事件等級,這個3個v就是輸出等級1至3的全部事件,而後再使用管道命令將輸出結果放到一個文本里面方便查看.接下來就是看你的程序能不能在這樣的折騰下堅持下去了.

 

實例:adb -s emulator-5556 shell monkey -p 包名 --ignore-crashes --ignore-timeouts --ignore-native-crashes --pct-touch 30 -s 1 -v -v --throttle 200 100000 2 logcat >C:/error.txt 1 logcat>C:/info.txt

(測試的時候須要先打開相應的應用,再測試)

 

5、Monkey log分析

(內容來自)

 Log 在android中的地位很是重要,要是做爲一個android程序員不能過度析log這關,算是android沒有入門吧。下面咱們就來講說如何處理log文件 。

(1)何時會有Log文件的產生 ?

 

Google Android如何分析和研究Log文件 ,如何看日誌信息 - 愛海濤濤 - Google Android
Log的產生你們都知道 , 你們也都知道經過DDMS來看log , 但何時會產生log文件呢 ?通常在以下幾種狀況會產生log文件 。 
  1. 程序異常退出 , uncaused exception
  2. 程序強制關閉 ,Force Closed (簡稱FC)
  3. 程序無響應 , Application No Response (簡稱ANR) , 順便,通常主線程超過5秒麼有處理就會ANR
  4. 手動生成 。



拿到一個日誌文件,要分紅多段來看 。 log文件很長,其中包含十幾個小單元信息,但不要被嚇到 ,事實上他主要由三大塊兒組成 。

1,系統基本信息 ,包括 內存,CPU ,進程隊列 ,虛擬內存 , 垃圾回收等信息 。
------ MEMORY INFO (/proc/meminfo) ------
------ CPU INFO (top -n 1 -d 1 -m 30 -t) ------
------ PROCRANK (procrank) ------
------ VIRTUAL MEMORY STATS (/proc/vmstat) ------
------ VMALLOC INFO (/proc/vmallocinfo) ------

格式以下:
------ MEMORY INFO (/proc/meminfo) ------
MemTotal:         347076 kB
MemFree:           56408 kB
Buffers:            7192 kB
Cached:           104064 kB
SwapCached:            0 kB
Active:           192592 kB
Inactive:          40548 kB
Active(anon):     129040 kB
Inactive(anon):     1104 kB
Active(file):      63552 kB
Inactive(file):    39444 kB
Unevictable:        7112 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                44 kB
Writeback:             0 kB
AnonPages:        129028 kB
Mapped:            73728 kB
Shmem:              1148 kB
Slab:              13072 kB
SReclaimable:       4564 kB
SUnreclaim:         8508 kB
KernelStack:        3472 kB
PageTables:        12172 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:      173536 kB
Committed_AS:    7394524 kB
VmallocTotal:     319488 kB
VmallocUsed:       90752 kB
VmallocChunk:     181252 kB


2,時間信息 , 也是咱們主要分析的信息 。
------ VMALLOC INFO (/proc/vmallocinfo) ------
------ EVENT INFO (/proc/vmallocinfo) ------

格式以下:
------ SYSTEM LOG (logcat -b system -v time -d *:v) ------
01-15 16:41:43.671 W/PackageManager( 2466): Unknown permission com.wsomacp.permission.PROVIDER in package com.android.mms
01-15 16:41:43.671 I/ActivityManager( 2466): Force stopping package com.android.mms uid=10092
01-15 16:41:43.675 I/UsageStats( 2466): Something wrong here, didn't expect com.sec.android.app.twlauncher to be paused
01-15 16:41:44.108 I/ActivityManager( 2466): Start proc com.sec.android.widgetapp.infoalarm for service com.sec.android.widgetapp.infoalarm/.engine.DataService: pid=20634 uid=10005 gids={3003, 1015, 3002}
01-15 16:41:44.175 W/ActivityManager( 2466): Activity pause timeout for HistoryRecord{48589868 com.sec.android.app.twlauncher/.Launcher}
01-15 16:41:50.864 I/KeyInputQueue( 2466): Input event
01-15 16:41:50.866 D/KeyInputQueue( 2466): screenCaptureKeyFlag setting 0
01-15 16:41:50.882 I/PowerManagerService( 2466): Ulight 0->7|0
01-15 16:41:50.882 I/PowerManagerService( 2466): Setting target 2: cur=0.0 target=70 delta=4.6666665 nominalCurrentValue=0
01-15 16:41:50.882 I/PowerManagerService( 2466): Scheduling light animator!
01-15 16:41:51.706 D/PowerManagerService( 2466): enableLightSensor true
01-15 16:41:51.929 I/KeyInputQueue( 2466): Input event
01-15 16:41:51.933 W/WindowManager( 2466): No focus window, dropping: KeyEvent{action=0 code=26 repeat=0 meta=0 scancode=26 mFlags=9}



3,虛擬機信息 , 包括進程的,線程的跟蹤信息,這是用來跟蹤進程和線程具體點的好地方 。 
------ VM TRACES JUST NOW (/data/anr/traces.txt.bugreport: 2011-01-15 16:49:02) ------
------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2011-01-15 16:49:02) ------


格式以下 :
----- pid 21161 at 2011-01-15 16:49:01 -----
Cmd line: com.android.mms

DALVIK THREADS:
"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x4001d8d0 self=0xccc8
  | sysTid=21161 nice=0 sched=0/0 cgrp=default handle=-1345017808
  | schedstat=( 4151552996 5342265329 10995 )
  at android.media.MediaPlayer._reset(Native Method)
  at android.media.MediaPlayer.reset(MediaPlayer.java:1218)
  at android.widget.VideoView.release(VideoView.java:499)
  at android.widget.VideoView.access$2100(VideoView.java:50)
  at android.widget.VideoView$6.surfaceDestroyed(VideoView.java:489)
  at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:572)
  at android.view.SurfaceView.updateWindow(SurfaceView.java:476)
  at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:206)
  at android.view.View.dispatchDetachedFromWindow(View.java:6082)
  at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
  at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:2296)
  at android.view.ViewGroup.removeAllViews(ViewGroup.java:2254)
  at com.android.mms.ui.SlideView.reset(SlideView.java:687)
  at com.android.mms.ui.SlideshowPresenter.presentSlide(SlideshowPresenter.java:189)
  at com.android.mms.ui.SlideshowPresenter$3.run(SlideshowPresenter.java:531)
  at android.os.Handler.handleCallback(Handler.java:587)
  at android.os.Handler.dispatchMessage(Handler.java:92)
  at android.os.Looper.loop(Looper.java:123)
  at android.app.ActivityThread.main(ActivityThread.java:4627)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:521)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
  at dalvik.system.NativeStart.main(Native Method)

---------------------------------------------------------------------------------------------------------------------------------------
閒話少說, 我總結了觀察log文件的基本步驟 。
1,若是是ANR問題 , 則搜索「ANR」關鍵詞 。 快速定位到關鍵事件信息 。
2,若是是ForceClosed 和其它異常退出信息,則搜索"Fatal" 關鍵詞, 快速定位到關鍵事件信息 。
3,定位到關鍵事件信息後 , 若是信息不夠明確的,再去搜索應用程序包的虛擬機信息 ,查看具體的進程和線程跟蹤的日誌,來定位到代碼 。 

用這種方法,出現問題,根本不須要斷點調試 , 直接定位到問題,屢試不爽 。 
下面,咱們就開始來分析這個例子的log 。

打開log文件 , 因爲是ANR錯誤,所以搜索"ANR " , 爲什麼要加空格呢,你加上和去掉比較一下就知道了 。 能夠屏蔽掉很多保存到anr.log文件的無效信息 。 

定位到關鍵的事件信息以下:
01-15 16:49:02.433 E/ActivityManager( 2466): ANR in com.android.mms (com.android.mms/.ui.SlideshowActivity)
01-15 16:49:02.433 E/ActivityManager( 2466): Reason: keyDispatchingTimedOut
01-15 16:49:02.433 E/ActivityManager( 2466): Load: 0.6 / 0.61 / 0.42
01-15 16:49:02.433 E/ActivityManager( 2466): CPU usage from 1337225ms to 57ms ago:
01-15 16:49:02.433 E/ActivityManager( 2466):   sensorserver_ya: 8% = 0% user + 8% kernel / faults: 40 minor
......


01-15 16:49:02.433 E/ActivityManager( 2466):  -com.android.mms: 0% = 0% user + 0% kernel
01-15 16:49:02.433 E/ActivityManager( 2466):  -flush-179:8: 0% = 0% user + 0% kernel
01-15 16:49:02.433 E/ActivityManager( 2466): TOTAL: 25% = 10% user + 14% kernel + 0% iowait + 0% irq + 0% softirq
01-15 16:49:02.436 I/        ( 2466): dumpmesg > "/data/log/dumpstate_app_anr.log"


咱們用天然語言來描述一下日誌,這也算是一種能力吧 。 
01-15 16:49:02.433 E/ActivityManager( 2466): ANR in com.android.mms (com.android.mms/.ui.SlideshowActivity)
翻譯:在16:49分2秒433毫秒的時候 ActivityManager (進程號爲2466) 發生了以下錯誤:com.android.mms包下面的.ui.SlideshowActivity 無響應 。

01-15 16:49:02.433 E/ActivityManager( 2466): Reason: keyDispatchingTimedOut
翻譯:緣由 , keyDispatchingTimeOut - 按鍵分配超時 

01-15 16:49:02.433 E/ActivityManager( 2466): Load: 0.6 / 0.61 / 0.42
翻譯:5分鐘,10分鐘,15分鐘內的平均負載分別爲:0.6 , 0.61 , 0.42

在這裏咱們大概知道問題是什麼了,結合咱們以前的操做流程,咱們知道問題是在點擊按鈕某時候可能處理不過來按鈕事件,致使超時無響應 。那麼如今彷佛已經能夠進行工做了 。 咱們知道Activity中是經過重載dispatchTouchEvent(MotionEvent ev)來處理點擊屏幕事件  。 而後咱們能夠順藤摸瓜,一點點分析去查找緣由 。 但這樣夠了麼 ?
其實不夠 , 至少咱們不能準確的知道到底問題在哪兒 , 只是猜想 ,好比這個應用程序中,我就在順藤摸瓜的時候發現了多個IO操做的地方都在主線程中,可能引發問題,但很差判斷究竟是哪一個  ,因此咱們目前掌握的信息還不夠 。 

因而咱們再分析虛擬機信息 , 搜索「Dalvik Thread」關鍵詞,快速定位到本應用程序的虛擬機信息日誌,以下:
----- pid 2922 at 2011-01-13 13:51:07 -----
Cmd line: com.android.mms

DALVIK THREADS:
"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x4001d8d0 self=0xccc8
  | sysTid=2922 nice=0 sched=0/0 cgrp=default handle=-1345017808
  | schedstat=( 3497492306 15312897923 10358 )
  at android.media.MediaPlayer._release(Native Method)
  at android.media.MediaPlayer.release(MediaPlayer.java:1206)
  at android.widget.VideoView.stopPlayback(VideoView.java:196)
  at com.android.mms.ui.SlideView.stopVideo(SlideView.java:640)
  at com.android.mms.ui.SlideshowPresenter.presentVideo(SlideshowPresenter.java:443)
  at com.android.mms.ui.SlideshowPresenter.presentRegionMedia(SlideshowPresenter.java:219)
  at com.android.mms.ui.SlideshowPresenter$4.run(SlideshowPresenter.java:516)
  at android.os.Handler.handleCallback(Handler.java:587)
  at android.os.Handler.dispatchMessage(Handler.java:92)
  at android.os.Looper.loop(Looper.java:123)
  at android.app.ActivityThread.main(ActivityThread.java:4627)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:521)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
  at dalvik.system.NativeStart.main(Native Method)

"Binder Thread #3" prio=5 tid=11 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x4837f808 self=0x242280
  | sysTid=3239 nice=0 sched=0/0 cgrp=default handle=2341032
  | schedstat=( 32410506 932842514 164 )
  at dalvik.system.NativeStart.run(Native Method)

"AsyncQueryWorker" prio=5 tid=9 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x482f4b80 self=0x253e10
  | sysTid=3236 nice=0 sched=0/0 cgrp=default handle=2432120
  | schedstat=( 3225061 26561350 27 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x482f4da8> (a android.os.MessageQueue)
  at java.lang.Object.wait(Object.java:288)
  at android.os.MessageQueue.next(MessageQueue.java:146)
  at android.os.Looper.loop(Looper.java:110)
  at android.os.HandlerThread.run(HandlerThread.java:60)

"Thread-9" prio=5 tid=8 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x4836e2b0 self=0x25af70
  | sysTid=2929 nice=0 sched=0/0 cgrp=default handle=2370896
  | schedstat=( 130248 4389035 2 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x4836e240> (a java.util.ArrayList)
  at java.lang.Object.wait(Object.java:288)
  at com.android.mms.data.Contact$ContactsCache$TaskStack$1.run(Contact.java:488)
  at java.lang.Thread.run(Thread.java:1096)

"Binder Thread #2" prio=5 tid=7 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x482f8ca0 self=0x130fd0
  | sysTid=2928 nice=0 sched=0/0 cgrp=default handle=1215968
  | schedstat=( 40610049 1837703846 195 )
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=6 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x482f4a78 self=0x128a50
  | sysTid=2927 nice=0 sched=0/0 cgrp=default handle=1201352
  | schedstat=( 40928066 928867585 190 )
  at dalvik.system.NativeStart.run(Native Method)

"Compiler" daemon prio=5 tid=5 VMWAIT
  | group="system" sCount=1 dsCount=0 s=N obj=0x482f1348 self=0x118960
  | sysTid=2926 nice=0 sched=0/0 cgrp=default handle=1149216
  | schedstat=( 753021350 3774113668 6686 )
  at dalvik.system.NativeStart.run(Native Method)

"JDWP" daemon prio=5 tid=4 VMWAIT
  | group="system" sCount=1 dsCount=0 s=N obj=0x482f12a0 self=0x132940
  | sysTid=2925 nice=0 sched=0/0 cgrp=default handle=1255680
  | schedstat=( 2827103 29553323 19 )
  at dalvik.system.NativeStart.run(Native Method)

"Signal Catcher" daemon prio=5 tid=3 RUNNABLE
  | group="system" sCount=0 dsCount=0 s=N obj=0x482f11e8 self=0x135988
  | sysTid=2924 nice=0 sched=0/0 cgrp=default handle=1173688
  | schedstat=( 11793815 12456169 7 )
  at dalvik.system.NativeStart.run(Native Method)

"HeapWorker" daemon prio=5 tid=2 VMWAIT
  | group="system" sCount=1 dsCount=0 s=N obj=0x45496028 self=0x135848
  | sysTid=2923 nice=0 sched=0/0 cgrp=default handle=1222608
  | schedstat=( 79049792 1520840200 95 )
  at dalvik.system.NativeStart.run(Native Method)

----- end 2922 -----

每一段都是一個線程 ,固然咱們仍是看線程號爲1的主線程了。經過分析發現關鍵問題是這樣:
  at com.android.mms.ui.SlideshowPresenter$3.run(SlideshowPresenter.java:531)
定位到代碼:
mHandler.post(new Runnable() {
                    public void run() {
                        try {
                            presentRegionMedia(view, (RegionMediaModel) model, dataChanged);
                        } catch (OMADRMException e) {
                            Log.e(TAG, e.getMessage(), e);
                            Toast.makeText(mContext,
                                    mContext.getString(R.string.insufficient_drm_rights),
                                    Toast.LENGTH_SHORT).show();
                        } catch (IOException e){
                            Log.e(TAG, e.getMessage(), e);
                            Toast.makeText(mContext,
                                    mContext.getString(R.string.insufficient_drm_rights),
                                    Toast.LENGTH_SHORT).show();
                        

                        }
                    }



很清楚了, Handler.post 方法以後執行時間太長的問題 。 繼續看presentRegionMedia(view, (RegionMediaModel) model, dataChanged);方法 , 發現最終是調用的framework 中MediaPlayer.stop方法 。
至此,咱們的日誌分析算是告一段落 。 能夠開始思考解決辦法了 。

 

 

 

思考:怎麼讓Monkey在機子上點擊快點
摘要: 1、解釋這個和手機的性能有關係,有的手機質量好,幾個小時就能弄完,但有的須要十幾個小時,這個好像只有等着了,在進行測試的時候有時候就卡在那裏了,你能夠手動幫忙讓手機動起來
 
思考2:出現「** System appears to have crashed at event 7487 of 10000 using seed 1437074235484」怎麼辦?
原來的測試語句是:
adb -s emulator-5554 shell monkey -p com.soft0754.android.tonze 10000
 
出現「** System appears to have crashed at event 7487 of 10000 using seed 1437074235484」的錯誤, 證實系統在10000個操做的第7487個操做裏出現了異常,用的種子是 14370742354841437074235484就是僞隨機數的種子。
 
咱們下次想用相同的操做序列再現這個異常,只須要:
 使用下面的測試語句:

adb -s emulator-5554 shell monkey -p com.soft0754.android.tonze -s 1437074235484 10000

可是操做的頁面須要相同,不然達不到相同的效果。可是,若是相同操做起點也就是相同的操做頁面執行命令沒法從新以前的BUG,就證實程序存在不穩定的因素。

相關文章
相關標籤/搜索