## 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截图:
![](https://box.kancloud.cn/2016-08-15_57b1755a4c165.jpg)
NoteEditor Activity截图:
![](https://box.kancloud.cn/2016-08-15_57b1755a707eb.jpg)
## 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',΢ÈíÑźÚ,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;交流