欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Monkey源碼分析之運(yùn)行流程

在《MonkeyRunner源碼分析之與Android設(shè)備通訊方式》中,我們談及到MonkeyRunner控制目標(biāo)android設(shè)備有多種方法,其中之一就是在目標(biāo)機(jī)器啟動一個monkey服務(wù)來監(jiān)聽指定的一個端口,然后monkeyrunner再連接上這個端口來發(fā)送命令,驅(qū)動monkey去完成相應(yīng)的工作。

創(chuàng)新互聯(lián)主要從事網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)吉利,10余年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108

當(dāng)時我們只分析了monkeyrunner這個客戶端的代碼是怎么實現(xiàn)這一點的,但沒有談monkey那邊是如何接受命令,接受到命令又是如何處理的。

所以自己打開源碼看了一個晚上,大概有了概念。但今天網(wǎng)上搜索了下,發(fā)現(xiàn)已經(jīng)有網(wǎng)友“chenjie”對monkey的源碼做過相應(yīng)的分析了,而且文章寫得非常有概括性,應(yīng)該是高手所為,果斷花了2個積分下載下來,不敢獨享,本想貼上來分享給大家,但發(fā)現(xiàn)pdf的文檔直接拷貝上來會丟失掉圖片,所以只好貼上下載地址:http://download.csdn.net/download/zqilu/6884491

但文章主要是架構(gòu)性得去描述monkey是怎么工作的,按照我自己的習(xí)慣,我還是喜歡按照自己的思維和有目的性的去了解我想要的,在這里我想要的是搞清楚monkey是如何處理monkeyrunner過來的命令的。

本文我們就先看下monkey的運(yùn)行流程。

1. 運(yùn)行環(huán)境設(shè)置

和monkeyrunner一樣,monkey這個命令也是一個shell腳本,它是在我們的目標(biāo)android設(shè)備的“/system/bin/monkey”,其實這是一個android上面java程序啟動的標(biāo)準(zhǔn)流程。

base=/system export CLASSPATH=$base/framework/monkey.jar trap "" HUP exec app_process $base/bin com.android.commands.monkey.Monkey $*
android中可以通過多種方式啟動java應(yīng)用,通過app_process命令啟動就是其中一種,它可以幫忙注冊android JNI,而繞過dalvik以使用Native API(如我般不清楚的請百度)所做的主要事情如下:

  • 設(shè)置monkey的CLASSPATH環(huán)境變量指向monkey.jar
  • 通過app_process指定monkey的入口和傳進(jìn)來的所有參數(shù)啟動上面CLASSPATH設(shè)定的monkey.jar

2.命令行參數(shù)解析

通過以上的app_process指定的monkey入口,我們可以知道我們的入口函數(shù)main是在com.android.commands.Monkey這個類里面的:
    /**      * Command-line entry point.      *      * @param args The command-line arguments      */     public static void main(String[] args) {         // Set the process name showing in "ps" or "top"         Process.setArgV0("com.android.commands.monkey");          int resultCode = (new Monkey()).run(args);         System.exit(resultCode);     } 
入口函數(shù)很簡單,直接跳到run這個方法,這是一個很重要的方法,里面大概會做以下這些事情:
  • 處理命令行參數(shù)
  • 根據(jù)命令行參數(shù)啟動不同的事件源,也就是我們的測試事件究竟是從網(wǎng)絡(luò)如monkeyrunner過來的還是monkey內(nèi)部的random測試數(shù)據(jù)集過來的還是腳本過來的如此之類
  • 跳入runMonkeyCyncle方法針對不同的事件源開始獲取并執(zhí)行不同的事件
這個方法會比較長,我們只看我們現(xiàn)在想要的關(guān)鍵片段,可以看到里面調(diào)用了命令行處理函數(shù)processOptions.
    private int run(String[] args) {     ...         if (!processOptions()) {             return -1;         }     ... }
進(jìn)去之后就是很普通的讀取命令行的參數(shù)然后一個個進(jìn)行解析保存了,沒有太多特別的東西,這里就直接貼出monkey的參數(shù)選項大家看看就好了:
Monkey源碼分析之運(yùn)行流程

3. 初始化測試事件源

如前所述,run方法里面在獲得命令行參數(shù)后會進(jìn)入下一個環(huán)節(jié),就是根據(jù)不同的參數(shù)去初始化不同的事件源
   private int run(String[] args) {         ...         if (mScriptFileNames != null && mScriptFileNames.size() == 1) {             // script mode, ignore other options             mEventSource = new MonkeySourceScript(mRandom, mScriptFileNames.get(0), mThrottle,                     mRandomizeThrottle, mProfileWaitTime, mDeviceSleepTime);             mEventSource.setVerbose(mVerbose);              mCountEvents = false;         } else if (mScriptFileNames != null && mScriptFileNames.size() > 1) {             if (mSetupFileName != null) {                 mEventSource = new MonkeySourceRandomScript(mSetupFileName,                         mScriptFileNames, mThrottle, mRandomizeThrottle, mRandom,                         mProfileWaitTime, mDeviceSleepTime, mRandomizeScript);                 mCount++;             } else {                 mEventSource = new MonkeySourceRandomScript(mScriptFileNames,                         mThrottle, mRandomizeThrottle, mRandom,                         mProfileWaitTime, mDeviceSleepTime, mRandomizeScript);             }             mEventSource.setVerbose(mVerbose);             mCountEvents = false;         } else if (mServerPort != -1) {             try {                 mEventSource = new MonkeySourceNetwork(mServerPort);             } catch (IOException e) {                 System.out.println("Error binding to network socket.");                 return -5;             }             mCount = Integer.MAX_VALUE;         } else {             // random source by default             if (mVerbose >= 2) { // check seeding performance                 System.out.println("// Seeded: " + mSeed);             }             mEventSource = new MonkeySourceRandom(mRandom, mMainApps, mThrottle, mRandomizeThrottle);             mEventSource.setVerbose(mVerbose);             // set any of the factors that has been set             for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {                 if (mFactors[i] <= 0.0f) {                     ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]);                 }             }              // in random mode, we start with a random activity             ((MonkeySourceRandom) mEventSource).generateActivity();         }         ...         mNetworkMonitor.start();         int crashedAtCycle = runMonkeyCycles();         mNetworkMonitor.stop();         ... }
事件源代表測試數(shù)據(jù)的事件是從哪里過來的,不同的event source會有不同的類來做相應(yīng)的實現(xiàn):
  • MonkeySourceNetwork.java: 事件是從網(wǎng)絡(luò)如monkeyrunner過來的,處理的是《MonkeyRunner源碼分析之與Android設(shè)備通訊方式》描述的界面控制操作事件
  • MonkeySourceNetworkVars.java: 事件也是從網(wǎng)絡(luò)如monkeyrunner過來的,處理的是《MonkeyRunner源碼分析之與Android設(shè)備通訊方式》提到的getPropery事件
  • MonkeySourceNetworkViews.java:事件也是從網(wǎng)絡(luò)如monkeyrunner過來的,處理的是《MonkeyRunner源碼分析之與Android設(shè)備通訊方式》提到的Views相關(guān)的事件
  • MonkeySourceRandom.java:事件是從monkey內(nèi)部生成的隨機(jī)事件集,也就是我們通過命令行啟動monkey測試目標(biāo)app的常用方式
  • MonkeySourceRanodomeScript.java: 上面的隨機(jī)內(nèi)部數(shù)據(jù)源也可以通過指定setup腳本來創(chuàng)建
  • MonkeySourceScript.java: 用戶也可以遵循一定的規(guī)則編寫monkey腳本來驅(qū)動monkey進(jìn)行相關(guān)測試,與上面不同的是它不再是隨機(jī)的
往后的文章我們會針對其中一個事件源進(jìn)行分析,在這里我們只需要知道這些事件源代表了事件的不同的來源,它會
  • 從指定的源獲取命令
  • 把命令翻譯成monkey事件然后放到命令隊列EventQueue
這里需要注意的是每一個EventSource類都是實現(xiàn)了MonkeyEventSource這個接口的,這個接口最重要的就是要求實現(xiàn)類必須實現(xiàn)getNextEvent這個方法來生成并獲取事件。這樣子做的好處就是屏蔽了每一個具體事件源的實現(xiàn)細(xì)節(jié),其他地方的代碼只需要調(diào)用這個接口的getNextEvent方法獲得事件源就行了,而無需關(guān)心這些事件是從哪個源過來的。這些都是面向?qū)ο蟮拿嫦蚪涌诰幊痰幕A(chǔ)了,大家有不清楚的最好先去了解下java的一些基本知識,這樣理解起來會快很多。

4. 循環(huán)執(zhí)行事件

run方法根據(jù)參數(shù)從不同的事件源獲得事件并放入到EventQueue后,就會開始執(zhí)行一個循環(huán)去從EventQueue里獲取事件進(jìn)行執(zhí)行
    private int run(String[] args) {         ...         int crashedAtCycle = runMonkeyCycles();         ... }
如前所述,runMonkeyCyles方法會根據(jù)不同的數(shù)據(jù)源開始一條條的獲取事件并進(jìn)行執(zhí)行:
    /**      * Run mCount cycles and see if we hit any crashers.      * <p>      * TODO: Meta state on keys      *      * @return Returns the last cycle which executed. If the value == mCount, no      *         errors detected.      */     private int runMonkeyCycles() {         int eventCounter = 0;         int cycleCounter = 0;          boolean shouldReportAnrTraces = false;         boolean shouldReportDumpsysMemInfo = false;         boolean shouldAbort = false;         boolean systemCrashed = false;          // TO DO : The count should apply to each of the script file.         while (!systemCrashed && cycleCounter < mCount) {                 ...             MonkeyEvent ev = mEventSource.getNextEvent();             if (ev != null) {                 int injectCode = ev.injectEvent(mWm, mAm, mVerbose);                 ...              }         ...         }        .... }
注意這里的mEventSource就是我們上面提到的事件源的接口,它屏蔽了每個事件實現(xiàn)類的具體細(xì)節(jié),我們只需要告訴這個接口我們現(xiàn)在需要取一條事件然后執(zhí)行它,該結(jié)構(gòu)根據(jù)面向?qū)ο蟮亩鄳B(tài)原理,就會自動取事件的實現(xiàn)類獲得對應(yīng)的事件進(jìn)行返回。
所以這里大家還需要對多態(tài)這個概念有所了解,特別是一些從手動測試轉(zhuǎn)到自動化測試的朋友,可能之前沒有接觸過太多面向?qū)ο蟮闹R。本人以前做過開發(fā),所以還ok。這里只是做一個善意的提醒。
獲得事件后下一步就是去執(zhí)行相應(yīng)的事件了,不同的事件會有不同的處理方式,或只是執(zhí)行個命令,或調(diào)用WindowManager隱藏接口做事件注入等,這些都會在今后文章進(jìn)行進(jìn)一步闡述

這一篇文章就到此為止了,目的就是讓大家對整一個monkey執(zhí)行的流程有個初步的了解,方便理解往下的相關(guān)文章。


       

      作者

      自主博客

      微信

      CSDN

      天地會珠海分舵

      http://techgogogo.com


      服務(wù)號:TechGoGoGo

      掃描碼:

      Monkey源碼分析之運(yùn)行流程

      Monkey源碼分析之運(yùn)行流程
      轉(zhuǎn)載來于:http://chinadenli.net/article48/giijep.html

      成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、網(wǎng)頁設(shè)計公司、服務(wù)器托管營銷型網(wǎng)站建設(shè)、移動網(wǎng)站建設(shè)、用戶體驗

      廣告

      聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)