亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MonkeyDevcie API 實踐全記錄

發布時間:2020-05-19 01:08:36 來源:網絡 閱讀:442 作者:zhukev 欄目:移動開發

1.    背景

使用SDK自帶的NotePad應用作為實踐目標應用,目的是對MonkeyDevice擁有的成員方法做一個初步的了解。

以下是官方列出的方法的Overview。

Return Type

Methods

Comment

void

broadcastIntent (string uri, string action, string data, string mimetype, 

iterable categories dictionary extras, component component, iterable flags)

Broadcasts an Intent to this device, as if the Intent were coming from an application.

 

void

drag (tuple start, tuple end, float duration, integer steps)

Simulates a drag gesture (touch, hold, and move) on this device's screen.

 

object

getProperty (string key)

Given the name of a system environment variable, returns its value for this device.

The available variable names are listed in the detailed description of this method.

 

object

getSystemProperty (string key)

. The API equivalent of adb shell getprop <key>. This is provided for

use by platform developers.

 

void

installPackage (string path)

Installs the Android application or test package contained in packageFile onto this device.

If the application or test package is already installed, it is replaced.

Obsolete,返回值是Boolean

dictionary

instrument (string className, dictionary args)

Runs the specified component under Android instrumentation, and returns the results

 in a dictionary whose exact format is dictated by the component being run.

 The component must already be present on this device.

 

void

press (string name, dictionary type)

Sends the key event specified by type to the key specified by keycode.

 

void

reboot (string into)

Reboots this device into the bootloader specified by bootloadType.

 

void

removePackage (string package)

Deletes the specified package from this device, including its data and cache.

 Obsolete,返回值是Boolean

object

shell (string cmd)

Executes an adb shell command and returns the result, if any.

 

void

startActivity (string uri, string action, string data, string mimetype, iterable categories 

dictionary extras, component component, flags)

Starts an Activity on this device by sending an Intent constructed from the supplied arguments.

 

MonkeyImage

takeSnapshot()

Captures the entire screen buffer of this device, yielding a MonkeyImage object containing

a screen capture of the current display.

 

void

touch (integer x, integer y, integer type)

Sends a touch event specified by type to the screen location specified by x and y.

 

void

type (string message)

Sends the characters contained in message to this device, as if they had been typed on

the device's keyboard. This is equivalent to callingpress() for each keycode in message 

using the key event type DOWN_AND_UP.

 

void

wake ()

Wakes the screen of this device.

 


其實官方這個表是沒有及時更新的,我現在手頭上用到的MonkeyRunner是當前最新的,里面就擁有好幾個官網沒有列出來的API,我懷疑是不是自從UIAutomator在03年出來后,google就不打算再繼續維護MonkeyRunner了?如果有朋友知道事實的話,還麻煩告知。

以下是我整理出來的源碼多出來的可用公共API列表

Return Type

Methods

Comment

HierarchyViewer

getHierarchyViewer(PyObject args[], String kws[])

獲取一個HierarchyViewer對象

 請查看《MonkenRunner通過HierarchyViewer定位控件的方法和建議》

PyList

getPropertyList(PyObject args[], String kws[])

 取得所有的property屬性鍵值

PyList

getViewIdList(PyObject args[], String kws[])

 Failed

MonkeyView

getViewById(PyObject args[], String kws[])

 Failed

MonkeyView

getViewByAccessibilityIds(PyObject args[], String kws[])

 Failed

MonkeyView

getRootView(PyObject args[], String kws[])

 Failed

PyList

getViewsByText(PyObject args[], String kws[])

 Failed

但可惜的是在本人嘗試以上多出來的API的時候,發現除了最上面兩個可用之外,其他的都不可用并拋出錯誤。且網上資料少的可憐,別人碰到同樣的問題也找不到解決辦法。所以本人懷疑這些“隱藏”API是不是并沒有完善,或者說google不準備完善,所以才沒有列出到官網上面去。本人用的SDK tools和Platform tools已經是當前最新的23.0.2和20.

一個臺灣網友碰到的問題描述:http://imsardine.simplbug.com/note/monkeyrunner/api/hierarchy-viewer.html


2.    Void broadcastIntent 

(string uri, string action,string data, string mimetype, iterable categories dictionary extras, componentcomponent, iterable flags)

2.1 分析

本人理解的此方法的本意是想廣播一個Intent給我們的AndroidDevice,目標應用接收到該Intent做相應的處理,比如打開一個Activity等。但在我的多次嘗試下并沒有成功

targetDevice.broadcastIntent(action='android.intent.action.INSERT',                            mimetype='vnd.android.cursor.dir/contact',                            extras = {'name':'user1501488', 'phone':'123-15489'} 

如果使用同樣的參數,使用下面的startActivity是沒有問題的。

targetDevice.startActivity(action='android.intent.action.INSERT',                            mimetype='vnd.android.cursor.dir/contact',                            extras = {'name':'user1501488', 'phone':'123-15489'}) 

google了半天網上根本找不到這個方法的使用例子,倒是stackOverFlow上有人建議用Shell來達到同樣的效果。

targetDevice.shell("am start -a android.intent.action.INSERT -t vnd.android.cursor.dir/contact -e name 'Donald Duck' -e phone 555-1234").

所以可見這個方法并沒有多少人在用,原因應該是它完全可以用上面介紹的兩個方法替代。


3. void startActivity 

(string uri, string action, string data, string mimetype, iterable categories dictionary extras, component component, flags)

3.1 示例

使用Action和mimetype來啟動一個Activity:
targetDevice.startActivity(action='android.intent.action.VIEW',                           mimetype='vnd.android.cursor.dir/vnd.google.note')

使用component來啟動一個Activity:
targetDevice.startActivity(component="com.example.android.notepad/com.example.android.notepad.NotesList")

使用action,mimetype和指定extras參數來啟動一個Activity:
targetDevice.startActivity(action='android.intent.action.INSERT',                            mimetype='vnd.android.cursor.dir/contact',                            extras = {'name':'user1501488', 'phone':'123-15489'})

3.2 分析

這個方法存在和以上的broadcastInt方法一樣擁有同樣的一大串參數,實例中只給出了本人已經跑通的例子,其他參數怎么用還有待深入研究,不過我相信對于我自己來說暫時這樣子已經足夠了。
另外需要注意的是參數中如果我們的填寫不是按順序從第一個參數開始的話,記得要在每個參數值前面指定你要傳入的是哪個參數,不然默認就會從第一個參數開始算,這是python的基本語法了,這里就不展開了。

4.  void drag (tuple start, tuple end, floatduration, integer steps)

這個方法的目的是按住一個控件然后把她拖動到其他位置

4.1 實例

viewer = targetDevice.getHierarchyViewer() note = viewer.findViewById('id/text1') point = viewer.getAbsoluteCenterOfView(note) startX = point.x startY = point.y  targetDevice.drag((startX,startY),(startX,startY),1)  targetDevice.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP) 

4.2 分析和建議

以上示例是通過drag的方法來模擬LongPress,只要把參數中的起始坐標和目標坐標都設置成同樣一個值,然后時常設置成一個有效的值就好了。


5 Object getProperty (string key)

 通過環境變量的key來獲得其對應的值。以下是官方提供的可用化境變量列表

Property Group

Property

Description

Notes

build

board

Code name for the device's system board

See Build

brand

The carrier or provider for which the OS is customized.

 

device

The device design name.

 

fingerprint

A unique identifier for the currently-running build.

 

host

 

 

ID

A changelist number or label.

 

model

The end-user-visible name for the device.

 

product

The overall product name.

 

tags

Comma-separated tags that describe the build, such as "unsigned" and "debug".

 

type

The build type, such as "user" or "eng".

 

user

 

 

CPU_ABI

The name of the native code instruction set, in the form CPU type plus ABI convention.

 

manufacturer

The product/hardware manufacturer.

 

version.incremental

The internal code used by the source control system to represent this version of the software.

 

version.release

The user-visible name of this version of the software.

 

version.sdk

The user-visible SDK version associated with this version of the OS.

 

version.codename

The current development codename, or "REL" if this version of the software has been released.

 

display

width

The device's display width in pixels.

SeeDisplayMetricsfor details.

height

The device's display height in pixels.

 

density

The logical density of the display. This is a factor that scales DIP (Density-Independent Pixel) units to the device's resolution. DIP is adjusted so that 1 DIP is equivalent to one pixel on a 160 pixel-per-inch display. For example, on a 160-dpi screen, density = 1.0, while on a 120-dpi screen, density = .75.

The value does not exactly follow the real screen size, but is adjusted to conform to large changes in the display DPI. See density for more details.

 

am.current

package

The Android package name of the currently running package.

The am.currentkeys return information about the currently-running Activity.

action

The current activity's action. This has the same format as the name attribute of the action element in a package manifest.

 

comp.class

The class name of the component that started the current Activity. See comp.package for more details.

 

comp.package

The package name of the component that started the current Activity. A component is specified by a package name and the name of class that the package contains.

 

data

The data (if any) contained in the Intent that started the current Activity.

 

categories

The categories specified by the Intent that started the current Activity.

 

clock

realtime

The number of milliseconds since the device rebooted, including deep-sleep time.

SeeSystemClock for more information.


5.1示例

displayWidth =targetDevice.getProperty ('display.width') printdisplayWidth.encode('utf-8')   displayHight =targetDevice.getProperty('display.width') printdisplayHight.encode('utf-8')  

5.2  分析和建議

以上示例的目的是獲得目標設備的長和高,當我們使用坐標點來操作控件的時候,調試的時候在一臺機器上通過了,但是如果換了另外一個屏幕大小不一樣的機器的話就會失敗,因為控件的坐標點位置可能就變了。這個時候我們就需要用到示例中的連個屬性來動態計算控件在不同屏幕大小的設備上面的坐標點了。

這里需要注意參數應該填寫的格式是以上列表中前兩列的組合PropertyGroup.Property


6. Object getSystemProperty (string key)

6.1 示例

displayWidth = targetDevice.getSystemProperty ('service.adb.tcp.port') print displayWidth.encode('utf-8') 

6.2 分析和建議

根據官網的描述,這個函數和getProperty函數應該有同樣的功能(Synonym for getProperty().),使用的屬性表也如上面的屬性列表一樣。但是按照我的實踐并非如此,不過它確實如官方描述的等同于命令“adb shell getprop <key>.”倒是真的。

以上的例子是獲取adb這個服務所打開的TCP端口,等同于如下的shell命令:“adb shell getprop service.adb.tcp.port

如果我嘗試使用下面的方法去獲得設備的長度,返回的結果其實會是None

displayWidth = targetDevice.getSystemProperty ('display.width') print displayWidth.encode('utf-8') 

7 Boolean installPackage (string path)

7.1示例

if True == targetDevice.installPackage('D:\\Projects\\Workspace\\PythonMonkeyRunnerDemo\\apps\\MPortal.apk'):    print "Installationfinished successfully" else:     print "Failedto install the apk"

7.2 分析和建議

這里有兩點需要注意的:

  • 官方網站描述的這個API是沒有返回值的(見背景中的表),而最新版本的API里面是Boolean值。
  • 參數輸入的應該是PC端這邊的Local路徑而非目標系統的Local路徑。

注意這里碰到一個路徑問題,如果我的路徑寫成:

'D:\Projects\Workspace\PythonMonkeyRunnerDemo\apps\MPortal.apk'

那么會出現下圖這樣的錯誤:

MonkeyDevcie API 實踐全記錄

如果在“apps”前面加多個轉義符就沒有問題:

'D:\Projects\Workspace\PythonMonkeyRunnerDemo\\apps\MPortal.apk'

所以這里MonkeyRunner處理路徑字串應該是存在Bug的,但是時間問題就先不去研究,建議所有路徑的話“\“都加上轉義符就好了

'D:\\Projects\\Workspace\\PythonMonkeyRunnerDemo\\apps\MPortal.apk'


8 boolean removePackage(string package)

8.1 示例

if True == targetDevice.removePackage('com.majcit.portal'):    print "Succeed toremove the package" else:     print "Failedto remove teh package"

8.2 注意事項

·        如上面的installPackageAPI一樣,官網描述的該API是沒有返回值的,而最新的是返回boolean


9. dictionary instrument (string className, dictionary args)

9.1 示例

只指定第一個參數(將會跑所有指定Component下的所有case+ NotePad項目本身的使用了Instrumentation的用例,具體意思請看下一節的分析)

dict = targetDevice.instrument('com.example.android.notepad.tryout/android.test.InstrumentationTestRunner') print dict 

指定只跑其中的一個Case:

dict = dict = targetDevice.instrument('com.example.android.notepad.tryout/android.test.InstrumentationTestRunner',                                       {'class':'com.example.android.notepad.tryout.TCCreateNote'}) print dict 

9.2 分析

這里首先需要看下官方的描述

Runs the specifiedcomponent under Android instrumentation, and returns the results in adictionary whose exact format is dictated by the component being run. Thecomponent must already be present on this device

這里重點是第一句“Runs the specified component under Android instrumentation“,剩下的是說返回值根據模塊不一樣而有所差別。那么第一句翻譯過來就是”運行使用了Anroid Instrumentation的指定模塊“。那么究竟什么是使用了Android Instrumentation的指定模塊呢?其實如果你有用過Robotium的話應該知道,腳本的每個case都是從Instrumentation相關的類中繼承下來的。

以下是本人之前寫的一個Robotium的測試case(具體請查看本人之前的一篇《Robotium創建一個Note的實例》,可以看到它是繼承于“ActivityInstrumentationTestCase2”的,其實它就滿足了剛才的描述“使用了Anroid Instrumentation的指定模塊“

package com.example.android.notepad.tryout;  import com.robotium.solo.Solo;  import android.test.ActivityInstrumentationTestCase2; import android.app.Activity;  @SuppressWarnings("rawtypes") public class TCCreateNote extends ActivityInstrumentationTestCase2{  	private static Solo solo = null; 	public Activity activity; 	 	private static final int NUMBER_TOTAL_CASES = 2; 	private static int run = 0; 	 	private static Class<?> launchActivityClass;  	//對應re-sign.jar生成出來的信息框里的兩個值 	private static String mainActiviy = "com.example.android.notepad.NotesList"; 	private static String packageName = "com.example.android.notepad";  	static {  		try {  			launchActivityClass = Class.forName(mainActiviy);  		} catch (ClassNotFoundException e) {  			throw new RuntimeException(e);  		}  	} 	 	 	@SuppressWarnings("unchecked") 	public TCCreateNote() { 		super(packageName, launchActivityClass); 	}  	 	@Override 	public void setUp() throws Exception { 		//setUp() is run before a test case is started.  		//This is where the solo object is created. 		super.setUp();  		//The variable solo has to be static, since every time after a case's finished, this class TCCreateNote would be re-instantiated 		// which would lead to soto to re-instantiated to be null if it's not set as static 		if(solo == null) { 			TCCreateNote.solo = new Solo(getInstrumentation(), getActivity()); 		} 	} 	 	@Override 	public void tearDown() throws Exception { 		//Check whether it's the last case executed. 		run += countTestCases(); 		if(run >= NUMBER_TOTAL_CASES) { 			solo.finishOpenedActivities(); 		} 	}  	public void testAddNoteCNTitle() throws Exception { 		 		solo.clickOnMenuItem("Add note"); 		solo.enterText(0, "中文標簽筆記"); 		solo.clickOnMenuItem("Save"); 		solo.clickInList(0); 		solo.clearEditText(0); 		solo.enterText(0, "Text 1"); 		solo.clickOnMenuItem("Save"); 		solo.assertCurrentActivity("Expected NotesList Activity", "NotesList"); 		 		solo.clickLongOnText("中文標簽筆記"); 		solo.clickOnText("Delete"); 	} 	 	 	public void testAddNoteEngTitle() throws Exception { 		solo.clickOnMenuItem("Add note"); 		solo.enterText(0, "English Title Note"); 		solo.clickOnMenuItem("Save"); 		solo.clickInList(0); 		solo.clearEditText(0); 		solo.enterText(0, "Text 1"); 		solo.clickOnMenuItem("Save"); 		solo.assertCurrentActivity("Expected NotesList Activity", "NotesList"); 		 		solo.clickLongOnText("English Title Note"); 		solo.clickOnText("Delete"); 	} } 

那么我們先在目標機器上執行命令“pm list instrumentation”看是否能列出這個“Component”:

MonkeyDevcie API 實踐全記錄

這其中哪一個是我們想要的呢?這要看我們的Robotium測試項目中的AndroidManifest.xml的定義了,根據下圖的packageName再對照上圖的輸出我們就定位到我們想要的Component了:

MonkeyDevcie API 實踐全記錄

如果我們調用這個方法的時候只是填寫了第一個參數的話,上圖處在”com.example.andriod.notepad.tryout”這個Component下的所有三個方法都會執行。但在我的測試中,發現除了跑這個Case之外,它還跑多了一些步驟,就是額外的多創建了一個Note1。我查了半天,發現原來我之前除了編寫了基于ActivityInstrumentationTestCase2Robotium的這個項目之外,還在NoetePad這個項目上直接用InstrumentationTestCase寫了一個基于Instrumentation的測試用例,做得事情就是增加一個Note1,具體請看本人另外一篇blog《SDK Instrumentation創建一個Note的實例

MonkeyDevcie API 實踐全記錄


其實調用這個方法相當于在shell腳本上執行如下的命令:

am instrument -w -r -e class com.example.android.notepad.tryout.TCCreateNote com.example.android.notepad.tryout/android.test.InstrumentationTestRunner

 

最后提一下的是,我們的腳本在執行示例的時候大概5秒左右就會失敗,但事實上在設備端所有的指定component的測試用例已經在執行的了。要解決這個問題需要重新編譯源碼,這里就免了,具體請查看:http://stackoverflow.com/questions/4264057/android-cts-is-showing-shellcommandunresponsiveexception-on-emulator

這里嘗試做一個簡單的總結

  • 調用此方法之前先要找到第一個參數怎么寫:執行命令“pm list instrumentation
  •  調用次方法如果不指定第一個參數會執行指定Component下面的所有測試腳本和目標應用包中所有用到Instrumentation的測試用例
  • 調用此方法最終事實上是在目標機器上根據指定的參數執行“am instrument xxxx”

10 void press (string name, integer type)

10.1 示例

targetDevice.press('KEYCODE_BACK',MonkeyDevice.DOWN_AND_UP)

10.2 分析

這個方法的目的是發送一個指定的Key事件到Android設備以觸發相應的動作,比如示例中發送“KEYCODE_BACK”這個key到設備端去觸發”返回“鍵的按下和升起(也就是點擊)的動作。

具體Key的Code請查看:http://developer.android.com/reference/android/view/KeyEvent.html

第二個參數是指導該Key應該如何Behave,比如先按下去,休眠一秒再彈起來(其實就相當于一個長按的動作)。具體支持behavior在本MonkeyDevice這個類的成員變量里有定義好:

Type

Constants

Notes

Comment

int官網是string,下同

DOWN

Use this with the type argument of press() or touch() to send a DOWN event.

 

int

UP

Use this with the type argument of press() or touch() to send an UP event.

 

int

DOWN_AND_UP

Use this with the type argument of press() or touch() to send a DOWN event immediately followed by an UP event.

 

int

MOVE

 TBD

官網沒有列出


11. void touch (integer x,integer y, integer type)

11.1 示例

viewer = targetDevice.getHierarchyViewer() note = viewer.findViewById('id/text1') point = viewer.getAbsoluteCenterOfView(note) startX = point.x startY = point.y  targetDevice.touch(startX,startY,MonkeyDevice.DOWN_AND_UP) 

11.2 分析

這個和上面的press方法在結果上有點類似,但是本方法是接受坐標進行點擊的,而上面方法接受的是keycode。

第二個參數同上。


12. void type (string message)

viewer =targetDevice.getHierarchyViewer()

note = viewer.findViewById('id/text1')

point = viewer.getAbsoluteCenterOfView(note)

startX = point.x

startY = point.y

targetDevice.touch(startX,startY,MonkeyDevice.DOWN_AND_UP)

MonkeyRunner.sleep(3)

targetDevice.type('NewContent')

12.1 示例

viewer = targetDevice.getHierarchyViewer() note = viewer.findViewById('id/text1') point = viewer.getAbsoluteCenterOfView(note) startX = point.x startY = point.y targetDevice.touch(startX,startY,MonkeyDevice.DOWN_AND_UP) MonkeyRunner.sleep(3) targetDevice.type('NewContent') 

12.2 分析

指定一串字符串進行模擬鍵盤輸入,等同于調用press方法按照一個一個的keycode用MonkeyDevice的DOWN_AND_UP進行輸入。

嘗試時發現中文不支持,鑒于項目不需要用到這種手機鍵盤,所以節省時間暫不研究。


13. Wake()

13.1示例

targetDevice.wake()

13.2 分析

注意這里只是喚醒屏保,如果手機已經鎖屏的話你是不能喚醒的。所以嘗試這個API的時候要注意把鎖屏功能先關閉掉。


14. MonkeyImange takeSnapshot()

14.1 示例

#Connect to the target targetDevice targetDevice = MonkeyRunner.waitForConnection()  easy_device = EasyMonkeyDevice(targetDevice)  #touch a button by id would need this targetDevice.startActivity(component="com.example.android.notepad/com.example.android.notepad.NotesList")  #invoke the menu options MonkeyRunner.sleep(6) #targetDevice.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP);  '''      public ViewNode findViewById(String id)       * @param id id for the view.      * @return view with the specified ID, or {@code null} if no view found. ''' #MonkeyRunner.alert("Continue?", "help", "Ok?")  pic = targetDevice.takeSnapshot() pic = pic.getSubImage((0,38,480,762))  newPic = targetDevice.takeSnapshot() newPic = newPic.getSubImage((0,38,480,762))  print (newPic.sameAs(pic,1.0)) newPic.writeToFile('./shot1.png','png')


14 object shell(string cmd)

14.1 示例

res = targetDevice.shell('ls /data/local/tmp|grep note') print res

14.2 分析

這個命令等同于你直接在命令行上“adb shell $command


15 void reboot(string into)

其他參數沒有用到所以也就沒有嘗試,僅僅嘗試了不帶參數的情況,結果就是直接reboot目標設備了

targetDevice.reboot()
這里有點需要提下的是,如果你是在MonkeyRunner命令行下執行這條命令的話,就算目標機器重啟,整個MonkeyRunner的環境還是依然有效的。也就是說你如果繼續打進一條"targetDevice.reboot()",你的設備就會再重啟一次。


 

作者

自主博客

微信

CSDN

天地會珠海分舵

http://techgogogo.com


服務號:TechGoGoGo

掃描碼:

MonkeyDevcie API 實踐全記錄

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

綦江县| 文昌市| 宁津县| 娄烦县| 新干县| 南丰县| 永嘉县| 大冶市| 衢州市| 治县。| 米泉市| 遂溪县| 微博| 蒙城县| 奇台县| 土默特右旗| 五原县| 绿春县| 鄂托克前旗| 高州市| 宜黄县| 长沙县| 镇沅| 邻水| 白玉县| 克拉玛依市| 孝感市| 哈尔滨市| 磐石市| 鄂伦春自治旗| 彝良县| 时尚| 邯郸县| 黄冈市| 商南县| 雅安市| 固阳县| 三江| 高碑店市| 义乌市| 铜鼓县|