您好,登錄后才能下訂單哦!
在《MonkeyRunner源碼分析之與Android設備通訊方式》中,我們談及到MonkeyRunner控制目標android設備有多種方法,其中之一就是在目標機器啟動一個monkey服務來監聽指定的一個端口,然后monkeyrunner再連接上這個端口來發送命令,驅動monkey去完成相應的工作。
當時我們只分析了monkeyrunner這個客戶端的代碼是怎么實現這一點的,但沒有談monkey那邊是如何接受命令,接受到命令又是如何處理的。
所以自己打開源碼看了一個晚上,大概有了概念。但今天網上搜索了下,發現已經有網友“chenjie”對monkey的源碼做過相應的分析了,而且文章寫得非常有概括性,應該是高手所為,果斷花了2個積分下載下來,不敢獨享,本想貼上來分享給大家,但發現pdf的文檔直接拷貝上來會丟失掉圖片,所以只好貼上下載地址:http://download.csdn.net/download/zqilu/6884491
但文章主要是架構性得去描述monkey是怎么工作的,按照我自己的習慣,我還是喜歡按照自己的思維和有目的性的去了解我想要的,在這里我想要的是搞清楚monkey是如何處理monkeyrunner過來的命令的。
本文我們就先看下monkey的運行流程。
base=/system export CLASSPATH=$base/framework/monkey.jar trap "" HUP exec app_process $base/bin com.android.commands.monkey.Monkey $*android中可以通過多種方式啟動java應用,通過app_process命令啟動就是其中一種,它可以幫忙注冊android JNI,而繞過dalvik以使用Native API(如我般不清楚的請百度)所做的主要事情如下:
/** * 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); }
private int run(String[] args) { ... if (!processOptions()) { return -1; } ... }進去之后就是很普通的讀取命令行的參數然后一個個進行解析保存了,沒有太多特別的東西,這里就直接貼出monkey的參數選項大家看看就好了:
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(); ... }事件源代表測試數據的事件是從哪里過來的,不同的event source會有不同的類來做相應的實現:
private int run(String[] args) { ... int crashedAtCycle = runMonkeyCycles(); ... }如前所述,runMonkeyCyles方法會根據不同的數據源開始一條條的獲取事件并進行執行:
/** * 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就是我們上面提到的事件源的接口,它屏蔽了每個事件實現類的具體細節,我們只需要告訴這個接口我們現在需要取一條事件然后執行它,該結構根據面向對象的多態原理,就會自動取事件的實現類獲得對應的事件進行返回。
作者 | 自主博客 | 微信 | CSDN |
天地會珠海分舵 | http://techgogogo.com | 服務號:TechGoGoGo 掃描碼:
| 向AI問一下細節 免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。 猜你喜歡最新資訊相關推薦相關標簽AI
助 手
蒙阴县|
那曲县|
石嘴山市|
镇宁|
泊头市|
河津市|
扎鲁特旗|
舟曲县|
揭西县|
神农架林区|
自贡市|
长葛市|
准格尔旗|
嘉黎县|
泰来县|
扶风县|
奉贤区|
栾城县|
资阳市|
方山县|
方城县|
千阳县|
海原县|
泗阳县|
鹤峰县|
纳雍县|
堆龙德庆县|
富阳市|
武清区|
伊金霍洛旗|
任丘市|
改则县|
蕉岭县|
华池县|
临高县|
突泉县|
灯塔市|
马关县|
南充市|
井研县|
汾阳市|
|