## 1. 前言
本來這次文章的title是寫成和前幾篇類似的《EasyMonkeyDevice API實踐全記錄》,內容也打算把每個API的實踐和建議給記錄下來,但后來想了下覺得這樣子并不是最好的方法,鑒于EasyMonkeyDevice其實就是在前幾章描述的MonkeyDevice和HierarchyViewer的基礎上加了一層Wrapper,把原來的通過接受坐標點或者ViewNode來操作控件的思想統一成通過控件ID來操作,其實最終它們都會轉換成坐標點或ViewNode進行操作。以touch和visible這兩個API為例子,大家看下以下的源碼就很清楚了。
MonkeyDevice里面的touch是用坐標點作為參數的,而下面的EasyMonkeyDevice用得是id(By這個類里面就一個ID而已,有興趣查其源碼),最終還是轉成坐標點:
~~~
public void touch(By selector, TouchPressType type)
{
Point p = getElementCenter(selector);
mDevice.getImpl().touch(p.x, p.y, type);
}
~~~
HierarchyViewer里面的Visible用的是ViewNode,EasyMonkeyDevice用得是id,最終還是轉成ViewNode:
~~~
public boolean visible(By selector)
{
ViewNode node = selector.findView(mHierarchyViewer);
return mHierarchyViewer.visible(node);
}
~~~
所以本文應該除了給出API的實踐之外還應該把每個API和其與MonkeyDevice和HierarchyViewer的API所對應的API給列出來做一個對應的Map,方便我們參考。
實踐中我們還是用SDK自帶的NotePad APK,假設已經有一個Note存在的情況下,通過以下步驟來走一遍EasyMonkeyDevice的所有API:
- 使用MonkeyDevice對象實例化EasyMonkeyDevice
- 通過ID Touch一個Note
- 獲得進入NoteEditor activity后的WindowId并驗證是否正確
- 通過ID檢查Note的內容這個EditText是否存在和可見
- 通過Note的ID獲得Text
- 通過Note的ID Type進新Text
- 通過Note的ID獲得Location
以下是我們操作過程中會看到的兩個Activity的截圖,先貼上來給大家對以上步驟有一個感性認識,最后我會貼出實踐驗證性代碼。
NotesList Activity截圖:

NoteEditor Activity截圖:

## 2. EaysyMonkeyDevice API List and Sample
EasyMonkeyDevice是在MonkeyDevice和HierarchyViewer的基礎上出來的一個類,按照本人的理解,主要增加的功能就是:
- 在MonkeyDevice和HierarchyViewer的基礎上針對部分API增加了對控件ID的支持以操作控件
以下是個人整理的列表:嘗試對所有的API進行一個描述和示例Demo
<table border="1" cellspacing="0" cellpadding="0" width="613"><tbody><tr><td valign="top" style="background-color:rgb(191,191,191)"><p align="center"><strong>Return</strong></p></td><td valign="top" style="background-color:rgb(191,191,191)"><p align="center"><strong>EasyMonkeyDevice</strong></p></td><td valign="top" style="background-color:rgb(191,191,191)"><p align="center"><strong>Demo</strong></p></td><td style="background-color:rgb(191,191,191)"><p align="center"><strong>Comment</strong></p><p align="center"><strong>?</strong></p></td></tr><tr><td valign="top"><p align="center"><strong><span style="color:rgb(49,132,155)">?</span></strong></p></td><td valign="top"><p><strong><span style="color:rgb(49,132,155)">EasyMonkeyDevice</span></strong><span style="color:rgb(34,34,34)">(</span></p><p><span style="color:rgb(34,34,34)">MonkeyDevice device)</span></p><p><em><span style="color:rgb(148,54,52)">Use Monkey device to construct</span></em></p><p><em><span style="color:rgb(148,54,52)">an EasyMonkeyDevice object,</span></em></p><p><em><span style="color:rgb(148,54,52)">note that it would instantiate a</span></em></p><p><em><span style="color:rgb(148,54,52)">HierarchyViewer member by</span></em></p><p><em><span style="color:rgb(148,54,52)">device within this constructor</span></em></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">device = MonkeyRunner.waitForConnection()</span></p><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">eDevice=EasyMonkeyDevice(device)</span></p></td><td><p><span style="color:rgb(34,34,34)">Constructor</span></p></td></tr><tr><td valign="top"><p align="center"><span style="color:rgb(34,34,34)">Void</span></p></td><td><p><strong><span style="color:rgb(49,132,155)">touch</span></strong><span style="color:rgb(34,34,34)">(By selector,</span></p><p><span style="color:rgb(34,34,34)">TouchPressType type)</span></p><p><em><span style="color:rgb(148,54,52)">Sends a touch event specified</span></em></p><p><em><span style="color:rgb(148,54,52)">by ‘type’ to the screen location</span></em></p><p><em><span style="color:rgb(148,54,52)">specified by ‘by’</span></em></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span><span style="color:rgb(34,34,34)">觸摸點擊主窗口:</span></p><p><span style="color:rgb(34,34,34)">#Step 1: try touching on the first note</span></p><p><span style="color:rgb(34,34,34)">eDevice.touch(By.id('id/text1'),</span></p><p><span style="color:rgb(34,34,34)">????????????? MonkeyDevice.DOWN_AND_UP)</span></p><p><span style="color:red">觸摸彈出框或</span><span style="color:red">Menu Options</span><span style="color:red">會失敗:</span></p><p><span style="color:rgb(34,34,34)">MonkeyRunner.sleep(2)</span></p><p><span style="color:rgb(34,34,34)">print 'Show Menu Options'</span></p><p><span style="color:rgb(34,34,34)">device.press('KEYCODE_MENU',</span></p><p><span style="color:rgb(34,34,34)">???????????? MonkeyDevice.DOWN_AND_UP);</span></p><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">MonkeyRunner.sleep(3)</span></p><p><span style="color:rgb(34,34,34)">print 'Press on the menu entry of \</span></p><p><span style="color:rgb(34,34,34)">?\"Add note\"'</span></p><p><span style="color:rgb(34,34,34)">eDevice.touch(By.id('id/title'),</span></p><p><span style="color:rgb(34,34,34)">?????????????? MonkeyDevice.DOWN)</span></p><p>?</p></td><td><p>參數By實際上</p><p>只有By.ID,從</p><p>其源碼可以看</p><p>出來;</p><p>type參數跟</p><p>MonkeyDevice</p><p>一樣就那幾個</p><p>DOWN/UP之類的</p><p>?</p><p><span style="color:red">根據個人實踐</span></p><p><span style="color:red">和網上評論,</span></p><p><span style="color:red">對系統菜單和</span></p><p><span style="color:red">彈出框的支持</span></p><p><span style="color:red">有問題</span></p></td></tr><tr><td valign="top"><p align="center"><span style="color:rgb(34,34,34)">Void</span></p></td><td><p><strong><span style="color:rgb(49,132,155)">type</span></strong><span style="color:rgb(34,34,34)">(By selector, String text)</span></p><p><em><span style="color:rgb(148,54,52)">Types a string into the specified</span></em></p><p><em><span style="color:rgb(148,54,52)">object</span></em></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">#Step 5: setText</span></p><p><span style="color:rgb(34,34,34)">eDevice.type(By.id(noteId), 'New')</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p align="center"><span style="color:rgb(34,34,34)">Boolean</span></p></td><td valign="top"><p><strong><span style="color:rgb(49,132,155)">exists</span></strong><span style="color:rgb(34,34,34)">(By selector)</span></p><p><em><span style="color:rgb(148,54,52)">Checks if the specified object</span></em></p><p><em><span style="color:rgb(148,54,52)">exists.</span></em></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">#Step3: is note EditText exist?</span></p><p><span style="color:rgb(34,34,34)">noteId = 'id/note'</span></p><p><span style="color:rgb(34,34,34)">if True == eDevice.exists(By.id(noteId)):</span></p><p><span style="color:rgb(34,34,34)">??? print 'Note exist'</span></p><p><span style="color:rgb(34,34,34)">else:</span></p><p><span style="color:rgb(34,34,34)">??? print 'Note not found!'</span></p><p><span style="color:rgb(34,34,34)">??? exit(2)</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p align="center"><span style="color:rgb(34,34,34)">Boolean</span></p></td><td valign="top"><p><strong><span style="color:rgb(49,132,155)">visible</span></strong><span style="color:rgb(34,34,34)">(By selector)</span></p><p><em><span style="color:rgb(148,54,52)">Checks if the specified object is visible.</span></em></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">#Step4: is note EditText visible?</span></p><p><span style="color:rgb(34,34,34)">if True == eDevice.visible(By.id(noteId)):</span></p><p><span style="color:rgb(34,34,34)">??? print 'Note is visible'</span></p><p><span style="color:rgb(34,34,34)">else:</span></p><p><span style="color:rgb(34,34,34)">??? print 'Note is invisible'</span></p><p><span style="color:rgb(34,34,34)">??? exit(3)</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p align="center"><span style="color:rgb(34,34,34)">String</span></p></td><td valign="top"><p><strong><span style="color:rgb(49,132,155)">getText</span></strong><span style="color:rgb(34,34,34)">(By selector)</span></p><p><em><span style="color:rgb(148,54,52)">Obtain the text in the selected</span></em></p><p><em><span style="color:rgb(148,54,52)">input box.</span></em></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">#Step 4: getText</span></p><p><span style="color:rgb(34,34,34)">text = eDevice.getText(By.id(noteId))</span></p><p><span style="color:rgb(34,34,34)">print 'Note text:',text.encode('utf-8')</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p align="center"><span style="color:rgb(34,34,34)">String</span></p></td><td valign="top"><p><strong><span style="color:rgb(49,132,155)">getFocusedWindowId</span></strong><span style="color:rgb(34,34,34)">()</span></p><p><em><span style="color:rgb(148,54,52)">Gets the id of the focused window.</span></em></p><p><span style="color:rgb(152,72,6)">returns = "</span><span style="color:rgb(0,176,80)">The symbolic id of the</span></p><p><span style="color:rgb(0,176,80)">focused window or None."</span></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">#Step 2: Get the window ID</span></p><p><span style="color:rgb(34,34,34)">winId = 'com.example.android.notepad/\</span></p><p><span style="color:rgb(34,34,34)">??? com.example.android.notepad.NoteEditor'</span></p><p><span style="color:rgb(34,34,34)">#Need to sleep a while till ready</span></p><p><span style="color:rgb(34,34,34)">MonkeyRunner.sleep(3)</span></p><p><span style="color:rgb(34,34,34)">winId = eDevice.getFocusedWindowId()</span></p><p><span style="color:rgb(34,34,34)">if(winId == winId):</span></p><p><span style="color:rgb(34,34,34)">?? ?print "Edit Note WinId is:",\</span></p><p><span style="color:rgb(34,34,34)">??????? winId.encode('utf-8')</span></p><p><span style="color:rgb(34,34,34)">else:</span></p><p><span style="color:rgb(34,34,34)">??? print "Failed"</span></p><p><span style="color:rgb(34,34,34)">??? exit(1)</span></p><p><span style="color:rgb(34,34,34)"><br/><br/></span></p></td><td><p><span style="color:rgb(34,34,34)">?</span><span style="color:rgb(34,34,34)">結果跟</span></p><p><span style="color:rgb(34,34,34)">HierarchyViewer</span></p><p><span style="color:rgb(34,34,34)">的</span></p><p><span style="color:rgb(34,34,34)">getFocusedWin</span></p><p><span style="color:rgb(34,34,34)">dowName</span></p><p><span style="color:rgb(34,34,34)">返回值一模</span></p><p><span style="color:rgb(34,34,34)">一樣,所以</span></p><p><span style="color:red">猜想</span><span style="color:red">WindowID</span></p><p><span style="color:red">和</span><span style="color:red">WindowName</span></p><p><span style="color:red">是同一回事</span></p></td></tr><tr><td valign="top"><p align="center"><span style="color:rgb(34,34,34)">PyTuple</span></p></td><td valign="top"><p><strong><span style="color:rgb(49,132,155)">locate</span></strong><span style="color:rgb(34,34,34)">(By selector)</span></p><p><span style="color:rgb(148,54,52)">Locates the coordinates of the</span></p><p><span style="color:rgb(148,54,52)">selected object</span></p><p><span style="color:rgb(148,54,52)">returns = "</span><span style="color:rgb(0,176,80)">Tuple containing</span></p><p><span style="color:rgb(0,176,80)">(x,y,w,h) location and size</span><span style="color:rgb(148,54,52)">.")</span></p></td><td valign="top"><p><span style="color:rgb(34,34,34)">?</span></p><p><span style="color:rgb(34,34,34)">#Step 6: locate</span></p><p><span style="color:rgb(34,34,34)">locate = eDevice.locate(By.id(noteId))</span></p><p><span style="color:rgb(34,34,34)">print 'Location(x,y,w,h) is:',locate</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr></tbody></table>
## 3. EasyMonkeyDevice vs MonkeyDevice API Mapping Matrix
這里會列出MonkeyDevice的所有API已經EasyMonkeyDevice與其對應的API,沒有去掉冗余是因為方便今后Reference的時候知道EasyMonkeyDevice并不是完全把所有MonkeyDevice的API都進行Wrap的,只有以下兩個。下面一章理同。
- **touch**:MonkeyDevice通過坐標點touch;EasyMonkeyDevice通過控件ID去touch
- **type**:MonkeyDevice往當前focused地方輸入;EasyMonkeyDevice往由ID指定控件輸入
<table border="1" cellspacing="0" cellpadding="0" width="685"><tbody><tr><td width="559" colspan="2" valign="top" style="background-color:rgb(191,191,191)"><p><strong>EasyMonkeyDevice API vs MonkeyDevice API</strong></p></td><td><p>?</p></td></tr><tr><td valign="top" style="background-color:rgb(191,191,191)"><p align="center"><strong>MonkeyDevice</strong></p></td><td valign="top" style="background-color:rgb(191,191,191)"><p><strong><span style="color:rgb(34,34,34)">EasyMonkeyDevice</span></strong></p></td><td style="background-color:rgb(191,191,191)"><p align="center"><strong>Comment</strong></p><p align="center"><strong>?</strong></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#broadcastIntent"><strong><span style="color:rgb(37,138,175)">broadcastIntent</span></strong></a><span style="color:rgb(34,34,34)">?(<em>string</em>?uri,?<em>string</em>?action,</span></p><p><span style="color:rgb(34,34,34)">?<em>string</em>?data,?<em>string</em>?mimetype,?</span></p><p><em><span style="color:rgb(148,54,52)">iterable</span></em><span style="color:rgb(148,54,52)">?categories?<em>dictionary</em>?extras,?</span></p><p><em><span style="color:rgb(148,54,52)">component</span></em><span style="color:rgb(148,54,52)">?component,?<em>iterable</em>?flags)</span></p><p><span style="color:rgb(148,54,52)">Broadcasts an Intent to this device, as if the</span></p><p><span style="color:rgb(148,54,52)">Intent were coming from an application.</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#drag"><span style="color:rgb(34,34,34)">drag</span></a><span style="color:rgb(34,34,34)">?(tuple?start,?tuple?end,?float?duration,?</span></p><p><span style="color:rgb(34,34,34)">integer?steps)</span></p><p><em><span style="color:rgb(148,54,52)">Simulates a drag gesture (touch, hold, and</span></em></p><p><em><span style="color:rgb(148,54,52)">move) on this device's screen.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Object</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#getProperty"><strong><span style="color:rgb(37,138,175)">getProperty</span></strong></a><span style="color:rgb(34,34,34)">?(string?key)</span></p><p><em><span style="color:rgb(148,54,52)">Given the name of a system environment</span></em></p><p><em><span style="color:rgb(148,54,52)">variable, returns its value for this device.</span></em></p><p><em><span style="color:rgb(148,54,52)">The available variable names are listed in</span></em></p><p><em><span style="color:rgb(148,54,52)">the?</span></em><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#getProperty"><em><span style="color:rgb(148,54,52)">detailed description</span></em></a><em><span style="color:rgb(148,54,52)">?of this method.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Object</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#getSystemProperty"><strong><span style="color:rgb(37,138,175)">getSystemProperty</span></strong></a><span style="color:rgb(34,34,34)">?(string?key)</span></p><p><em><span style="color:rgb(0,176,80)">.?</span><span style="color:rgb(148,54,52)">The API equivalent of?adb shell getprop</span></em></p><p><em><span style="color:rgb(148,54,52)"><key>. This is provided for</span></em></p><p><em><span style="color:rgb(148,54,52)">use by platform developers.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#installPackage"><strong><span style="color:rgb(37,138,175)">installPackage</span></strong></a><span style="color:rgb(34,34,34)">?(string?path)</span></p><p><em><span style="color:rgb(148,54,52)">Installs the Android application or test package</span></em></p><p><em><span style="color:rgb(148,54,52)">?contained in packageFile onto this device.</span></em></p><p><em><span style="color:rgb(148,54,52)">If the application or test package is already</span></em></p><p><em><span style="color:rgb(148,54,52)">installed, it is replaced.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Dictionary</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#instrument"><strong><span style="color:rgb(37,138,175)">instrument</span></strong></a><span style="color:rgb(34,34,34)">?(string?className,?dictionary?args)</span></p><p><em><span style="color:rgb(148,54,52)">Runs the specified component under</span></em></p><p><em><span style="color:rgb(148,54,52)">Android instrumentation, and returns the results</span></em></p><p><em><span style="color:rgb(148,54,52)">?in a dictionary whose exact format is dictated</span></em></p><p><em><span style="color:rgb(148,54,52)">by the component being run.</span></em></p><p><em><span style="color:rgb(148,54,52)">?The component must already be present on</span></em></p><p><em><span style="color:rgb(148,54,52)">this device.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#press"><strong><span style="color:rgb(37,138,175)">press</span></strong></a><span style="color:rgb(34,34,34)">?(<em>string</em>?name,?<em>dictionary</em>?type)</span></p><p><em><span style="color:rgb(148,54,52)">Sends the key event specified by type to the</span></em></p><p><em><span style="color:rgb(148,54,52)">key specified by keycode.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#reboot"><strong><span style="color:rgb(37,138,175)">reboot</span></strong></a><span style="color:rgb(34,34,34)">?(<em>string</em>?into)</span></p><p><em><span style="color:rgb(148,54,52)">Reboots this device into the bootloader</span></em></p><p><em><span style="color:rgb(148,54,52)">specified by bootloadType.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#removePackage"><strong><span style="color:rgb(37,138,175)">removePackage</span></strong></a><span style="color:rgb(34,34,34)">?(<em>string</em>?package)</span></p><p><em><span style="color:rgb(148,54,52)">Deletes the specified package from this device,</span></em></p><p><em><span style="color:rgb(148,54,52)">?including its data and cache.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><em><span style="color:rgb(34,34,34)">Object</span></em><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#shell"><strong><span style="color:rgb(37,138,175)">shell</span></strong></a><span style="color:rgb(34,34,34)">?(<em>string</em>?cmd)</span></p><p><em><span style="color:rgb(148,54,52)">Executes an?adb?shell command and returns</span></em></p><p><em><span style="color:rgb(148,54,52)">the result, if any.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#startActivity"><strong><span style="color:rgb(37,138,175)">startActivity</span></strong></a><span style="color:rgb(34,34,34)">?(string?uri,?string?action,?</span></p><p><span style="color:rgb(34,34,34)">string</span><span style="color:rgb(34,34,34)">?data,?string?mimetype,?iterable?categories?</span></p><p><span style="color:rgb(34,34,34)">dictionary</span><span style="color:rgb(34,34,34)">?extras,?component?component,?flags)</span></p><p><em><span style="color:rgb(148,54,52)">Starts an Activity on this device by sending an</span></em></p><p><em><span style="color:rgb(148,54,52)">Intent constructed from the supplied arguments</span><span style="color:rgb(0,176,80)">.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><a target="_blank" href="http://developer.android.com/tools/help/MonkeyImage.html"><span style="color:rgb(34,34,34)">MonkeyImage</span></a><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#takeSnapshot"><strong><span style="color:rgb(37,138,175)">takeSnapshot</span></strong></a><span style="color:rgb(34,34,34)">()</span></p><p><em><span style="color:rgb(148,54,52)">Captures the entire screen buffer of this device,</span></em></p><p><em><span style="color:rgb(148,54,52)">yielding a?<a target="_blank" href="http://developer.android.com/tools/help/MonkeyImage.html"><span style="color:rgb(148,54,52)">MonkeyImage?</span></a>object containing</span></em></p><p><em><span style="color:rgb(148,54,52)">a screen capture of the current display.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#touch"><strong><span style="color:rgb(37,138,175)">touch</span></strong></a><span style="color:rgb(34,34,34)">?(<em>integer</em>?x,?<em>integer</em>?y,?<em>integer</em>?type)</span></p><p><em><span style="color:rgb(148,54,52)">Sends a touch event specified by type to the</span></em></p><p><em><span style="color:rgb(148,54,52)">screen location specified by x and y.</span></em></p></td><td><p><span style="color:rgb(34,34,34)">Void</span><strong><span style="color:rgb(49,132,155)">?touch</span></strong><span style="color:rgb(34,34,34)">(By selector, TouchPressType type)</span></p><p><em><span style="color:rgb(148,54,52)">Sends a touch event specified by</span></em></p><p><em><span style="color:rgb(148,54,52)">‘type’ to the screen location specified</span></em></p><p><em><span style="color:rgb(148,54,52)">?by ‘by’</span></em></p></td><td><p><span style="color:red">MonkeyDevice</span><span style="color:red">通過坐標點</span><span style="color:red">touch</span><span style="color:red">;</span></p><p><span style="color:red">EasyMonkeyDevice</span><span style="color:red">通過控件</span><span style="color:red">ID</span><span style="color:red">去</span><span style="color:red">touch</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#touch"><strong><span style="color:rgb(37,138,175)">type</span></strong></a><span style="color:rgb(34,34,34)">?(<em>string</em>?message)</span></p><p><span style="color:rgb(148,54,52)">Sends the characters contained in message to</span></p><p><span style="color:rgb(148,54,52)">this device, as if they had been typed on</span></p><p><span style="color:rgb(148,54,52)">the device's keyboard. This is equivalent to</span></p><p><span style="color:rgb(148,54,52)">calling?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#press"><span style="color:rgb(148,54,52)">press()</span></a><span style="color:rgb(148,54,52)">?for each keycode in?<strong>message</strong>?</span></p><p><span style="color:rgb(148,54,52)">using the key event type?<strong>DOWN_AND_UP.</strong></span></p></td><td><p><span style="color:rgb(34,34,34)">Void?</span><strong><span style="color:rgb(49,132,155)">type</span></strong><span style="color:rgb(34,34,34)">(By selector, String text)</span></p><p><span style="color:rgb(148,54,52)">Types a string into the specified</span></p><p><span style="color:rgb(148,54,52)">object</span></p></td><td><p><span style="color:red">MonkeyDevice</span><span style="color:red">往當前</span><span style="color:red">focused</span><span style="color:red">地方輸入;</span></p><p><span style="color:red">EasyMonkeyDevice</span><span style="color:red">往由</span><span style="color:red">ID</span><span style="color:red">指定控件輸入</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">Void?</span><a target="_blank" href="http://developer.android.com/tools/help/MonkeyDevice.html#touch"><strong><span style="color:rgb(37,138,175)">wake</span></strong></a><span style="color:rgb(34,34,34)">?()</span></p><p><span style="color:rgb(148,54,52)">Wakes the screen of this device.</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">HierarchyViewer</span>?<strong><span style="color:rgb(37,138,175)">getHierarchyViewer</span></strong>()</p><p><span style="color:rgb(148,54,52)">Get the HierarchyViewer object for the device.</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">PyList</span><strong><span style="color:rgb(37,138,175)">getPropertyList</span></strong>()</p><p><span style="color:rgb(148,54,52)">Retrieve the properties that can be queried</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">PyList</span><strong><span style="color:rgb(37,138,175)">getViewIdList</span></strong>()</p><p><span style="color:rgb(148,54,52)">Retrieve the view ids for the current application</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">MonkeyView</span><strong><span style="color:rgb(37,138,175)">getViewById</span></strong>(String id)</p><p><span style="color:rgb(148,54,52)">doc = "Obtains the view with the specified id.",</span></p><p><span style="color:rgb(148,54,52)">args = {"id"},</span></p><p><span style="color:rgb(148,54,52)">argDocs = {"The id of the view to retrieve."},</span></p><p><span style="color:rgb(148,54,52)">returns = "The view object with the specified id."</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">MonkeyView</span><strong><span style="color:rgb(37,138,175)">getViewByAccessibilityIds</span></strong>(String WinId, String accessId)</p><p><span style="color:rgb(148,54,52)">args = {"windowId", "accessibility id"}</span></p><p><span style="color:rgb(148,54,52)">argDocs = {"The window id of the view to</span></p><p><span style="color:rgb(148,54,52)">retrieve.", "The accessibility id of the view to</span></p><p><span style="color:rgb(148,54,52)">retrieve."},</span></p><p><span style="color:rgb(148,54,52)">returns = "The view object with the specified id.")</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">MonkeyView</span><strong><span style="color:rgb(37,138,175)">getRootView</span></strong>()</p><p><span style="color:rgb(148,54,52)">Obtains current root view</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(34,34,34)">PyList</span><strong><span style="color:rgb(37,138,175)">getViewsByText</span></strong>(String text)</p><p><span style="color:rgb(148,54,52)">Obtains a list of views that contain the specified</span></p><p><span style="color:rgb(148,54,52)">text.",</span></p><p><span style="color:rgb(148,54,52)">args = {"text"},</span></p><p><span style="color:rgb(148,54,52)">returns = "A list of view objects that contain the specified text.")</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr></tbody></table>
## 4. EasyMonkeyDevice vs HierarchyViewer Mapping Matrix
EasyMonkeyDevice Wrap了HiearchyViewer 的相應API而得到以下這些API
- getFocusedWindowId:Wrap了hierarchyviewer的getFocusedWindowName,不再使用ViewNode而使用ID來的獲得Window id/Name,其實根據我的實踐id/name是同一回事
- locate:其實就是把HierarchyViewer的getAbsolutePositionOfView和getAbsoluteCenterOfView整合在一起獲得起始坐標和Width/Hight,前者獲得其實坐標,后者獲得中心位置,相減后乘以2就是EasyMonkeyDevice想要的Width/Hight了
- visible: 同樣是把參數由ViewNode改成id
- getText:同上
<table border="1" cellspacing="0" cellpadding="0" width="685"><tbody><tr><td width="559" colspan="2" valign="top" style="background-color:rgb(191,191,191)"><p><strong>EasyMonkeyDevice API vs HierarchViewer API</strong></p></td><td><p>?</p></td></tr><tr><td valign="top" style="background-color:rgb(191,191,191)"><p align="center"><strong>HierarchyViewer</strong></p></td><td valign="top" style="background-color:rgb(191,191,191)"><p><strong><span style="color:rgb(34,34,34)">EasyMonkeyDevice</span></strong></p></td><td style="background-color:rgb(191,191,191)"><p align="center"><strong>Comment</strong></p><p align="center"><strong>?</strong></p></td></tr><tr><td valign="top"><p><span style="color:rgb(0,0,136)">public</span>?<span style="color:rgb(102,0,102)">ViewNode</span>?findViewById<span style="color:rgb(102,102,0)">(</span><span style="color:rgb(102,0,102)">String</span>?id<span style="color:rgb(102,102,0)">)</span></p><div><p><span style="color:rgb(136,0,0)">/**</span></p><p><a target="_blank" name="66" class=" "/><span style="color:rgb(136,0,0)">* Find a view by id.</span><a target="_blank" name="67" class=" "/></p><p><a target="_blank" name="68" class=" "/><span style="color:rgb(136,0,0)">* @param id id for the view.</span></p><p><a target="_blank" name="69" class=" "/><span style="color:rgb(136,0,0)">* @return view with the specified ID, or {@code null} if no view found.</span></p><p><a target="_blank" name="70" class=" "/><span style="color:rgb(136,0,0)">*/</span></p></div><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(0,0,136)">public</span>?<span style="color:rgb(102,0,102)">ViewNode</span>?findViewById<span style="color:rgb(102,102,0)">(</span><span style="color:rgb(102,0,102)">String</span>?id<span style="color:rgb(102,102,0)">,</span>?<span style="color:rgb(102,0,102)">ViewNode</span>?rootNode<span style="color:rgb(102,102,0)">)</span></p><div><p><span style="color:rgb(136,0,0)">/**</span></p><p><a target="_blank" name="82" class=" "/><span style="color:rgb(136,0,0)">* Find a view by ID, starting from the given root node</span></p><p><a target="_blank" name="83" class=" "/><span style="color:rgb(136,0,0)">* @param id ID of the view you're looking for</span></p><p><a target="_blank" name="84" class=" "/><span style="color:rgb(136,0,0)">* @param rootNode the ViewNode at which to begin the traversal</span></p><p><a target="_blank" name="85" class=" "/><span style="color:rgb(136,0,0)">* @return view with the specified ID, or {@code null} if no view found.</span></p><p><a target="_blank" name="86" class=" "/><span style="color:rgb(136,0,0)">*/</span></p></div></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(0,0,136)">public</span>?<span style="color:rgb(102,0,102)">String</span>?getFocusedWindowName<span style="color:rgb(102,102,0)">()</span></p><div><p><span style="color:rgb(136,0,0)">/**</span></p><p><a target="_blank" name="103" class=" "/><span style="color:rgb(136,0,0)">* Gets the window that currently receives the focus.</span><a target="_blank" name="104" class=" "/></p><p><a target="_blank" name="105" class=" "/><span style="color:rgb(136,0,0)">* @return name of the window that currently receives the focus.</span></p><p><a target="_blank" name="106" class=" "/><span style="color:rgb(136,0,0)">*/</span></p></div><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(102,0,102)">String?</span><span style="color:rgb(34,34,34)">getFocusedWindowId()</span></p><p><span style="color:rgb(148,54,52)">Gets the id of the focused window.</span></p><p><span style="color:rgb(148,54,52)">returns = "The symbolic id of the focused window or None</span><span style="color:rgb(152,72,6)">."</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><div><p><span style="color:rgb(0,0,136)">public</span>?<span style="color:rgb(0,0,136)">static</span>?<span style="color:rgb(102,0,102)">Point</span>?getAbsolutePositionOfView<span style="color:rgb(102,102,0)">(</span><span style="color:rgb(102,0,102)">ViewNode</span>?node<span style="color:rgb(102,102,0)">)</span><span style="color:rgb(136,0,0)">/**</span></p></div><div><p><a target="_blank" name="118" class=" "/><span style="color:rgb(136,0,0)">* Gets the absolute x/y position of the view node.</span></p><p><a target="_blank" name="119" class=" "/><span style="color:rgb(136,0,0)">*</span></p><p><a target="_blank" name="120" class=" "/><span style="color:rgb(136,0,0)">* @param node view node to find position of.</span></p><p><a target="_blank" name="121" class=" "/><span style="color:rgb(136,0,0)">* @return point specifying the x/y position of the node.</span></p><p><a target="_blank" name="122" class=" "/><span style="color:rgb(136,0,0)">*/</span></p></div><p><span style="color:rgb(34,34,34)">?</span></p></td><td rowspan="2"><p><span style="color:rgb(0,0,136)">PyTuple</span><span style="color:rgb(34,34,34)">?locate(By selector)</span></p><p><span style="color:rgb(148,54,52)">Locates the coordinates of the selected object</span></p><p><span style="color:rgb(148,54,52)">returns = "Tuple containing (x,y,w,h) location and size.")</span></p></td><td rowspan="2"><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(0,0,136)">public</span>?<span style="color:rgb(0,0,136)">static</span>?<span style="color:rgb(102,0,102)">Point</span>?getAbsoluteCenterOfView<span style="color:rgb(102,102,0)">(</span><span style="color:rgb(102,0,102)">ViewNode</span>?node<span style="color:rgb(102,102,0)">)</span></p><div><p><span style="color:rgb(136,0,0)">/**</span></p><p><a target="_blank" name="136" class=" "/><span style="color:rgb(136,0,0)">* Gets the absolute x/y center of the specified view node.</span></p><p><a target="_blank" name="137" class=" "/><span style="color:rgb(136,0,0)">*</span></p><p><a target="_blank" name="138" class=" "/><span style="color:rgb(136,0,0)">* @param node view node to find position of.</span></p><p><a target="_blank" name="139" class=" "/><span style="color:rgb(136,0,0)">* @return absolute x/y center of the specified view node.</span></p><p><a target="_blank" name="140" class=" "/><span style="color:rgb(136,0,0)">*/</span></p></div></td></tr><tr><td valign="top"><p><span style="color:rgb(0,0,136)">public</span>?<span style="color:rgb(0,0,136)">boolean</span>?visible<span style="color:rgb(102,102,0)">(</span><span style="color:rgb(102,0,102)">ViewNode</span>?node<span style="color:rgb(102,102,0)">)</span></p><div><p><span style="color:rgb(136,0,0)">/**</span></p><p><a target="_blank" name="148" class=" "/><span style="color:rgb(136,0,0)">* Gets the visibility of a given element.</span><a target="_blank" name="149" class=" "/></p><p><a target="_blank" name="150" class=" "/><span style="color:rgb(136,0,0)">* @param selector selector for the view.</span></p><p><a target="_blank" name="151" class=" "/><span style="color:rgb(136,0,0)">* @return True if the element is visible.</span></p><p><a target="_blank" name="152" class=" "/><span style="color:rgb(136,0,0)">*/</span></p></div><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(0,0,136)">boolean</span><span style="color:rgb(34,34,34)">?visible(By selector)</span></p><p><span style="color:rgb(148,54,52)">Checks if the specified object is visible.</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr><tr><td valign="top"><p><span style="color:rgb(0,0,136)">public</span>?<span style="color:rgb(102,0,102)">String</span>?getText<span style="color:rgb(102,102,0)">(</span><span style="color:rgb(102,0,102)">ViewNode</span>?node<span style="color:rgb(102,102,0)">)</span></p><div><p><span style="color:rgb(136,0,0)">/**</span></p><p><a target="_blank" name="163" class=" "/><span style="color:rgb(136,0,0)">* Gets the text of a given element.</span></p><p><a target="_blank" name="164" class=" "/><span style="color:rgb(136,0,0)">*</span></p><p><a target="_blank" name="165" class=" "/><span style="color:rgb(136,0,0)">* @param selector selector for the view.</span></p><p><a target="_blank" name="166" class=" "/><span style="color:rgb(136,0,0)">* @return the text of the given element.</span></p><p><a target="_blank" name="167" class=" "/><span style="color:rgb(136,0,0)">*/</span></p></div><p><span style="color:rgb(34,34,34)">?</span></p></td><td><p><span style="color:rgb(0,0,136)">String</span><span style="color:rgb(34,34,34)">?getText(By selector)</span></p><p><span style="color:rgb(148,54,52)">Obtain the text in the selected input box.</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr></tbody></table>
## 5. EasyMonkeyDevice Standalone API
剩下一個API是沒有跟以上的MonkeyDevice和HierarchyViewer有任何對應關系的:
- visible:通過id檢查該控件是否存在,猜想應該是google在代碼重構的時候增加的一個方法方便大家判斷而已
<table border="1" cellspacing="0" cellpadding="0" width="685"><tbody><tr><td valign="top" style="background-color:rgb(191,191,191)"><p><strong>EasyMonkeyDevice Standalone API</strong></p></td><td><p>?</p></td></tr><tr><td valign="top" style="background-color:rgb(191,191,191)"><p align="center"><strong>EasyMonkeDevice</strong></p></td><td style="background-color:rgb(191,191,191)"><p align="center"><strong>Comment</strong></p><p align="center"><strong>?</strong></p></td></tr><tr><td valign="top"><p><span style="color:rgb(0,0,136)">boolean</span><span style="color:rgb(34,34,34)">?exists(By selector)</span></p><p><span style="color:rgb(148,54,52)">Checks if the specified object exists.</span></p></td><td><p><span style="color:rgb(34,34,34)">?</span></p></td></tr></tbody></table>
## 6. 驗證性代碼
~~~
from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage
from com.android.monkeyrunner.easy import EasyMonkeyDevice,By
from com.android.chimpchat.hierarchyviewer import HierarchyViewer
from com.android.hierarchyviewerlib.models import ViewNode, Window
from java.awt import Point
#from com.android.hierarchyviewerlib.device import
#Connect to the target device
device = MonkeyRunner.waitForConnection()
eDevice=EasyMonkeyDevice(device)
device.startActivity(component="com.example.android.notepad/com.example.android.notepad.NotesList")
'''
MonkeyRunner.sleep(2)
print 'Show Menu Options'
device.press('KEYCODE_MENU',
MonkeyDevice.DOWN_AND_UP);
MonkeyRunner.sleep(3)
print 'Press on the menu entry of \
\"Add note\"'
eDevice.touch(By.id('id/title'),
MonkeyDevice.DOWN)
MonkeyRunner.sleep(2)
device.press('KEYCODE_MENU',
MonkeyDevice.DOWN_AND_UP);
'''
#Step 1: try touching on the first note
eDevice.touch(By.id('id/text1'),
MonkeyDevice.DOWN_AND_UP)
#Step 2: Get the window ID
winId = 'com.example.android.notepad/\
com.example.android.notepad.NoteEditor'
#Need to sleep a while till ready
MonkeyRunner.sleep(3)
winId = eDevice.getFocusedWindowId()
if(winId == winId):
print "Edit Note WinId is:",\
winId.encode('utf-8')
else:
print "Failed"
exit(1)
#Step3: is note EditText exist?
noteId = 'id/note'
if True == eDevice.exists(By.id(noteId)):
print 'Note exist'
else:
print 'Note not found!'
exit(2)
#Step4: is note EditText visible?
if True == eDevice.visible(By.id(noteId)):
print 'Note is visible'
else:
print 'Note is invisible'
exit(3)
#Step 4: getText
text = eDevice.getText(By.id(noteId))
print 'Note text:',text.encode('utf-8')
#Step 5: setText
eDevice.type(By.id(noteId), 'New')
#Step 6: locate
locate = eDevice.locate(By.id(noteId))
print 'Location(x,y,w,h) is:',locate
~~~
## 7. EasyMonkeyDevice Source Code for Your Reference?
~~~
/*jadclipse*/// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
package com.android.monkeyrunner.easy;
import com.android.chimpchat.hierarchyviewer.HierarchyViewer;
import com.android.hierarchyviewerlib.models.ViewNode;
import com.android.monkeyrunner.JythonUtils;
import com.google.common.base.Preconditions;
import org.python.core.*;
public class By extends PyObject
implements ClassDictInit
{
public static void classDictInit(PyObject dict)
{
JythonUtils.convertDocAnnotationsForClass(com/android/monkeyrunner/easy/By, dict);
}
By(String id)
{
this.id = id;
}
public static By id(PyObject args[], String kws[])
{
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
String id = ap.getString(0);
return new By(id);
}
public static By id(String id)
{
return new By(id);
}
public ViewNode findView(HierarchyViewer viewer)
{
return viewer.findViewById(id);
}
private String id;
}
/*
DECOMPILATION REPORT
Decompiled from: D:\Projects\Workspace\JarPackages\monkeyrunner.jar
Total time: 69 ms
Jad reported messages/errors:
The class file version is 50.0 (only 45.3, 46.0 and 47.0 are supported)
Exit status: 0
Caught exceptions:
*/
~~~
## 8. By Class Source Code for Your Better Reference
~~~
/*jadclipse*/// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
package com.android.monkeyrunner.easy;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.TouchPressType;
import com.android.chimpchat.hierarchyviewer.HierarchyViewer;
import com.android.hierarchyviewerlib.models.ViewNode;
import com.android.monkeyrunner.JythonUtils;
import com.android.monkeyrunner.MonkeyDevice;
import com.google.common.base.Preconditions;
import java.util.Set;
import org.eclipse.swt.graphics.Point;
import org.python.core.*;
// Referenced classes of package com.android.monkeyrunner.easy:
// By
public class EasyMonkeyDevice extends PyObject
implements ClassDictInit
{
public static void classDictInit(PyObject dict)
{
JythonUtils.convertDocAnnotationsForClass(com/android/monkeyrunner/easy/EasyMonkeyDevice, dict);
}
public EasyMonkeyDevice(MonkeyDevice device)
{
mDevice = device;
mHierarchyViewer = device.getImpl().getHierarchyViewer();
}
public void touch(PyObject args[], String kws[])
{
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
By selector = getSelector(ap, 0);
String tmpType = ap.getString(1);
TouchPressType type = TouchPressType.fromIdentifier(tmpType);
Preconditions.checkNotNull(type, (new StringBuilder()).append("Invalid touch type: ").append(tmpType).toString());
touch(selector, type);
}
public void touch(By selector, TouchPressType type)
{
Point p = getElementCenter(selector);
mDevice.getImpl().touch(p.x, p.y, type);
}
public void type(PyObject args[], String kws[])
{
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
By selector = getSelector(ap, 0);
String text = ap.getString(1);
type(selector, text);
}
public void type(By selector, String text)
{
Point p = getElementCenter(selector);
mDevice.getImpl().touch(p.x, p.y, TouchPressType.DOWN_AND_UP);
mDevice.getImpl().type(text);
}
public PyTuple locate(PyObject args[], String kws[])
{
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
By selector = getSelector(ap, 0);
ViewNode node = selector.findView(mHierarchyViewer);
Point p = HierarchyViewer.getAbsolutePositionOfView(node);
PyTuple tuple = new PyTuple(new PyObject[] {
new PyInteger(p.x), new PyInteger(p.y), new PyInteger(node.width), new PyInteger(node.height)
});
return tuple;
}
public boolean exists(PyObject args[], String kws[])
{
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
By selector = getSelector(ap, 0);
return exists(selector);
}
public boolean exists(By selector)
{
ViewNode node = selector.findView(mHierarchyViewer);
return node != null;
}
public boolean visible(PyObject args[], String kws[])
{
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
By selector = getSelector(ap, 0);
return visible(selector);
}
public boolean visible(By selector)
{
ViewNode node = selector.findView(mHierarchyViewer);
return mHierarchyViewer.visible(node);
}
public String getText(PyObject args[], String kws[])
{
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
By selector = getSelector(ap, 0);
return getText(selector);
}
public String getText(By selector)
{
ViewNode node = selector.findView(mHierarchyViewer);
return mHierarchyViewer.getText(node);
}
public String getFocusedWindowId(PyObject args[], String kws[])
{
return getFocusedWindowId();
}
public String getFocusedWindowId()
{
return mHierarchyViewer.getFocusedWindowName();
}
public PyObject __findattr_ex__(String name)
{
if(!EXPORTED_METHODS.contains(name))
return mDevice.__findattr_ex__(name);
else
return super.__findattr_ex__(name);
}
private By getSelector(ArgParser ap, int i)
{
return (By)ap.getPyObject(i).__tojava__(com/android/monkeyrunner/easy/By);
}
private Point getElementCenter(By selector)
{
ViewNode node = selector.findView(mHierarchyViewer);
if(node == null)
{
throw new PyException(Py.ValueError, String.format("View not found: %s", new Object[] {
selector
}));
} else
{
Point p = HierarchyViewer.getAbsoluteCenterOfView(node);
return p;
}
}
private MonkeyDevice mDevice;
private HierarchyViewer mHierarchyViewer;
private static final Set EXPORTED_METHODS = JythonUtils.getMethodNames(com/android/monkeyrunner/easy/EasyMonkeyDevice);
}
/*
DECOMPILATION REPORT
Decompiled from: D:\Projects\Workspace\JarPackages\monkeyrunner.jar
Total time: 920 ms
Jad reported messages/errors:
The class file version is 50.0 (only 45.3, 46.0 and 47.0 are supported)
Exit status: 0
Caught exceptions:
*/
~~~
<table cellspacing="0" cellpadding="0" width="539" class=" " style="margin:0px 0px 10px; padding:0px; border-collapse:collapse; width:668px; max-width:100%; word-wrap:break-word!important"><tbody style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><tr style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><td valign="top" width="112" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important">?</td></tr><tr style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><td valign="top" width="111" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">作者</span></p></td><td valign="top" width="112" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">自主博客</span></p></td><td valign="top" width="111" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">微信</span></p></td><td valign="top" width="112" height="13" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(190,192,191)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important">CSDN</span></p></td></tr><tr style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"><td valign="top" width="111" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important; background-color:rgb(227,228,228)"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">天地會珠海分舵</span></p></td><td valign="top" width="112" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; font-size:11px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important"><a target="_blank" href="http://techgogogo.com/">http://techgogogo.com</a></span><span style="margin:0px; padding:0px; max-width:100%; font-family:Helvetica; font-size:11px; letter-spacing:0px; word-wrap:break-word!important"/></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:14px; white-space:pre-wrap; font-family:Helvetica; word-wrap:break-word!important"><br style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important"/></p></td><td valign="top" width="111" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">服務號</span><span style="margin:0px; padding:0px; max-width:100%; font-size:10px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important">:TechGoGoGo</span></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; word-wrap:break-word!important">掃描碼</span><span style="margin:0px; padding:0px; max-width:100%; font-size:10px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important">:</span></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:14px; white-space:pre-wrap; font-family:Helvetica; word-wrap:break-word!important"><img src="image/47cf4f9ec59b0ef1f807a6c33ab5ce5f.jpg" alt="" style="max-width:100%; margin:0px; padding:0px; height:auto!important; word-wrap:break-word!important; width:auto!important; visibility:visible!important"/></p></td><td valign="top" width="112" height="39" style="border-style:solid; border-color:rgb(0,0,0); margin:0px; padding:4px; word-break:break-all; max-width:100%; word-wrap:break-word!important"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; max-width:100%; clear:both; min-height:1em; white-space:pre-wrap; color:rgb(62,62,62); font-family:'Helvetica Neue',Helvetica,'Hiragino Sans GB','Microsoft YaHei',?¢èí??oú,Arial,sans-serif; font-size:18px; line-height:28.7999992370605px; word-wrap:break-word!important"><span style="margin:0px; padding:0px; max-width:100%; color:rgb(0,0,0); font-size:11px; font-family:Helvetica; letter-spacing:0px; word-wrap:break-word!important"><a target="_blank" href="http://blog.csdn.net/zhubaitian">http://blog.csdn.net/zhubaitian</a></span><span style="margin:0px; padding:0px; max-width:100%; color:rgb(0,0,0); font-family:Helvetica; font-size:11px; letter-spacing:0px; line-height:28.7999992370605px; word-wrap:break-word!important"/></p><div><span style="margin:0px; padding:0px; max-width:100%; color:rgb(0,0,0); font-family:Helvetica; font-size:11px; letter-spacing:0px; line-height:28.7999992370605px; word-wrap:break-word!important"><br/></span></div></td></tr></tbody></table>
- 前言
- MonkeyRunner創建一個Note的實例
- MonkeyRunner在Windows下的Eclipse開發環境搭建步驟(兼解決網上Jython配置出錯的問題)
- MonkenRunner通過HierarchyViewer定位控件的方法和建議(Appium/UIAutomator/Robotium姊妹篇)
- MonkeyDevcie API 實踐全記錄
- MonkeyImage API 實踐全記錄
- EasyMonkeyDevice vs MonkeyDevice&amp;HierarchyViewer API Mapping Matrix
- adb概覽及協議參考
- MonkeyRunner源碼分析之-誰動了我的截圖?
- MonkeyRunner源碼分析之與Android設備通訊方式
- MonkeyRunner源碼分析之啟動
- Monkey源碼分析之運行流程
- Monkey源碼分析之事件源
- Monkey源碼分析番外篇之WindowManager注入事件如何跳出進程間安全限制
- Monkey源碼分析番外篇之Android注入事件的三種方法比較
- Monkey源碼分析之事件注入
- monkey源碼分析之事件注入方法變化
- MonkeyRunner源碼分析之工作原理圖
- Android自動化測試框架新書:&lt;&lt;MonnkeyRunner實現原理剖析&gt;&gt;交流