Time will tell.
在前面的章節(jié)里,分享了通過獲取控件坐標(biāo)點(diǎn)來獲取點(diǎn)擊事件所需要的點(diǎn)擊位置届囚,那么還有其他獲取控件點(diǎn)擊事件所需要點(diǎn)擊位置的方法嗎颓影?當(dāng)然有。
在不同大小屏幕的手機(jī)上獲取控件的坐標(biāo)點(diǎn)妇穴,不是一樣的。因此在不同的機(jī)型上需要重新獲取坐標(biāo)點(diǎn)隶债。如果操作控件特別多腾它,那么獲取控件的坐標(biāo)點(diǎn)就會(huì)特別繁瑣。因此可以通過獲取控件 ID 來避免獲取控件坐標(biāo)點(diǎn)的這種弊端死讹。
控件 ID 的獲取主要通過HierarchyViewer
瞒滴,下面從打開和使用兩方面進(jìn)行講解。
1赞警、HierarchyViewer 打開方式
HierarchyViewer
的打開方式有兩種:
一種是eclipse中打開HierarchyView視圖妓忍;
第二種是命令行中執(zhí)行sdk/tools/hierarchyviewer.bat。
HierarchyViewer
默認(rèn)只能在非加密設(shè)備使用愧旦,例如工程機(jī)世剖,工程平板或者模擬器。如果要在手機(jī)上使用HierarchyViewer
笤虫,你需要在你的應(yīng)用中添加一個(gè)開源庫(kù)View Server
旁瘫。鏈接地址:https://github.com/romainguy/ViewServer ,里面有講解如何啟動(dòng)真機(jī)View Server
琼蚯。
方式一:
連接你的真機(jī)設(shè)備或打開模擬器酬凳,在 eclipse 中, 依次選擇 Window - Open Perspective - Other遭庶,在 Other 中宁仔,選擇HierarchyView
視圖,即可打開罚拟。
方式二:
連接您的真機(jī)設(shè)備或打開模擬器台诗,運(yùn)行 cmd 窗口完箩,進(jìn)入到 sdk/tools 目錄下,輸入命令hierarchyviewer.bat
拉队,運(yùn)行hierarchyviewer
弊知。
或直接在 sdk/tools 目錄下,找到hierarchyviewer.bat
粱快,雙擊運(yùn)行秩彤。
未開啟夜神模擬器的HierarchyViewer
:
開啟夜神模擬器后的HierarchyViewer
:
2、HierarchyViewer 獲取控件 ID
HierarchyViewer
啟動(dòng)后事哭,首先會(huì)看到的第一個(gè)窗口顯示了設(shè)備和模擬器的列表漫雷。點(diǎn)擊左邊的箭頭,就會(huì)展開當(dāng)前設(shè)備或模擬器的Activity
對(duì)象列表鳍咱。列表中顯示了設(shè)備或模擬器上降盹, UI 當(dāng)前可視的所有Activity
對(duì)象。
這些對(duì)象按照它們的 Android 組件名稱列出來谤辜。列表中的內(nèi)容包含應(yīng)用的Activity
對(duì)象和系統(tǒng)的Activity
對(duì)象蓄坏。
當(dāng)模擬器Activity
畫面變更后,點(diǎn)擊refresh
可以加載新的頁(yè)面布局信息丑念。
從列表中選擇你的 activity 名稱涡戳,雙擊,或點(diǎn)擊菜單欄的 Load View Hierarchy
按鈕脯倚,進(jìn)入View Hierarchy
窗口渔彰,查看它的view
層次結(jié)構(gòu);或者點(diǎn)擊 Inspect Screenshot
按鈕推正,進(jìn)入Pixel Perfect
窗口恍涂,從而查看 UI 的一個(gè)放大圖像。我們這里點(diǎn)擊進(jìn)入View Hierarchy
窗口舔稀。
從下圖中看到模擬器此 activity 的畫面布局信息乳丰,左邊部分是hierarchy
通過樹形結(jié)構(gòu)展示的布局形式,右下角是模擬器上當(dāng)前頁(yè)面的 UI 布局信息内贮。
通過滾動(dòng)鼠標(biāo),可以放大每個(gè)樹節(jié)點(diǎn)汞斧。拖拽鼠標(biāo)夜郁,移動(dòng)樹形結(jié)構(gòu)布局。雙擊樹節(jié)點(diǎn)可以展示單獨(dú)的 UI 部分粘勒。從下圖中竞端,可以看到,id/btn_login
即為登錄按鈕的 ID 庙睡。依次類推事富,可以查看其它控件 ID 技俐。
對(duì)于列表、或者彈出框則無法直接通過點(diǎn)擊 ID 操作成功统台,需要計(jì)算 ID 的坐標(biāo)雕擂。
3、控件 ID 之 Monkeyrunner 腳本演示
同樣贱勃,我們將下面一段 Monkeyrunner 腳本寫到一個(gè)test.py
文件中井赌,然后運(yùn)行test.py
文件,查看模擬器上是不是做相應(yīng)的操作贵扰。
# coding=utf-8
# 1.先設(shè)置編碼仇穗,utf-8可支持中英文,如上戚绕,一般放在第一行
# 2.注釋:包括記錄創(chuàng)建時(shí)間纹坐,創(chuàng)建人,項(xiàng)目名稱舞丛。
# 3.導(dǎo)入模塊
from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
from com.android.monkeyrunner.easy import EasyMonkeyDevice #提供了根據(jù)ID進(jìn)行訪問
from com.android.monkeyrunner.easy import By #根據(jù)ID返回PyObject的方法
device=MonkeyRunner.waitForConnection()
#啟動(dòng)activity(這里啟動(dòng)qq)
device.startActivity(component="com.tencent.mobileqq/.activity.SplashActivity")
easy_device=EasyMonkeyDevice(device) #必須在activity啟動(dòng)之后
#登錄界面耘子,點(diǎn)擊賬號(hào)輸入框
easy_device.touch(By.id('id/0x20e'),MonkeyDevice.DOWN_AND_UP)
device.type('721471592') #輸入qq賬號(hào)
至此,獲取控件ID的方式已經(jīng)介紹完瓷马,由于沒有深入研究拴还,肯定有不少功能點(diǎn)沒有介紹到,有時(shí)間的話再做完善欧聘。
4片林、控件 ID 不存在或重復(fù)
在用 monkeyrunner 進(jìn)行 Android 自動(dòng)化時(shí),通過獲取坐標(biāo)點(diǎn)或控件 ID 進(jìn)行一系列操作怀骤。由于使用坐標(biāo)點(diǎn)時(shí)费封,屏幕分辨率一旦更改,則代碼中用到坐標(biāo)的地方都要修改蒋伦,這樣導(dǎo)致代碼的復(fù)用率較低弓摘。因此,我們多采用控件 ID 操作痕届,注意控件 ID 需要在模擬器中使用韧献,對(duì)于絕大多數(shù)真機(jī)不適用。但是研叫,某些控件的 ID 是不存在的或重復(fù)存在锤窑,那么,遇到這種情況嚷炉,我們?cè)鯓永^續(xù)使用控件 ID 進(jìn)行自動(dòng)化測(cè)呢渊啰?
例如,下圖中,我想要獲取最右側(cè)紅框中的 id/tv 绘证,但是隧膏,大家會(huì)發(fā)現(xiàn),和它并列的也有重復(fù)的控件 id 值∪履牵現(xiàn)在我們就講述一下這種情況(控件 ID 不存在同樣處理)胞枕。
我們從這個(gè)控件樹的節(jié)點(diǎn)角度來思考如何獲得控件的引用。我們可以看到在上圖hierarchy viewer
中的每個(gè)控件所對(duì)應(yīng)的框形中车酣,右下角都有一個(gè)數(shù)字曲稼。其實(shí)這個(gè)數(shù)字就是該控件在同級(jí)兄弟節(jié)點(diǎn)中的索引值,我們知道這個(gè)索引值后湖员,就可以根據(jù)parentView.children[index]
屬性來獲取任意父節(jié)點(diǎn)所對(duì)應(yīng)的子節(jié)點(diǎn)的對(duì)象引用贫悄。其中的parentView
可以是樹形圖中有效 ID 的任意父節(jié)點(diǎn)(父節(jié)點(diǎn)要保證唯一有效),然后利用python
函數(shù)的可變參數(shù)列表特性來傳入所需控件的索引列表即可構(gòu)造出得到任意節(jié)點(diǎn)引用的字符串娘摔,從而得到其引用窄坦。
核心代碼如下,把如下代碼加入自己的 python 腳本中凳寺,直接調(diào)用該函數(shù)即可鸭津。
#定義獲取重復(fù)或不存在控件id,尋找子節(jié)點(diǎn)函數(shù)
def getChildView(parentId, *childSeq):
hierarchyViewer = device.getHierarchyViewer()
childView="hierarchyViewer.findViewById('" + parentId +"')"
for index in childSeq:
childView += ('.children[' + str(index) + ']')
print childView
return eval(childView)
#獲取id的文本
def getText(view):
if view != None:
return (view.namedProperties.get('text:mText').value)
有了以上代碼之后肠缨,我們可以獲取上圖中的 id/tv 逆趋,方法如下:
getChildView('id/province_list',5,0,0)
其中結(jié)合上圖可知,getChildView
的第一個(gè)參數(shù)即:有效且唯一的父節(jié)點(diǎn)
參數(shù)二晒奕、三依次為要獲取的控件 ID 的父節(jié)點(diǎn)的父節(jié)點(diǎn)
注:用到的父節(jié)點(diǎn)即圖中的id/province_list
闻书,有效且唯一的值。當(dāng)前的父節(jié)點(diǎn)右下角的角標(biāo)脑慧,不需要在getChildView
函數(shù)中顯示魄眉。
這樣,通過以上函數(shù)闷袒,再結(jié)合Hierarchyviewer
圖形坑律,我們獲取到了重復(fù)的控件ID。
由于Hierarchyviewer
看起來不是特別方便囊骤,這里再推薦一款和Hierarchyviewer
類似功能的工具:uiautomatorviewer(存儲(chǔ)在sdk\tools
中晃择,雙擊打開即可)。
由上圖中也物,uiautomatorviewer
每個(gè)控件前面的數(shù)字即相當(dāng)于Hierarchyviewer
的角標(biāo)藕各,我們同樣可以獲取到目標(biāo) ID 的最終有效且唯一的父節(jié)點(diǎn),從而調(diào)用函數(shù)getChildView('id/province_list',5,0,0)
獲取到了不存在或重復(fù)的控件 ID 后焦除,我們可以通過其坐標(biāo),進(jìn)行點(diǎn)擊操作作彤。
首先膘魄,定義一個(gè) “獲取指定按鈕坐標(biāo)” 的函數(shù)
def getBtnPoint(btn):
print btn
point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn);
return point
然后我們可以通過坐標(biāo)乌逐,實(shí)現(xiàn)點(diǎn)擊操作,例如:
askView = getChildView('id/tabs',1)
askPpoint = getBtnPoint(askView)
device.touch(askPpoint.x,askPpoint.y,'DOWN_AND_UP')
至此创葡,我們介紹完了處理控件 ID 不存在或重復(fù)時(shí)的方法浙踢,有興趣的小伙伴或者童鞋們可以自己動(dòng)手實(shí)踐一把,就會(huì)更能體會(huì)Hierarchyviewer/uiautomatorviewer
+ getChildView()
獲取不存在或重復(fù)控件 ID 的用法灿渴、樂趣及其奧秘洛波。
大概意思是說,單獨(dú)版本的hieararchyviewer
已經(jīng)被棄用了骚露。請(qǐng)使用 Android Device Monitor 來代替蹬挤。Android Device Monitor 在 tools 目錄下面找到monitor.bat
即可。
為了緊跟時(shí)代潮流棘幸,就決定用 Android Device Monitor 啟動(dòng)即可焰扳。
具體操作啟動(dòng)步驟:
1、運(yùn)行命令monitor.bat
误续,如下:
2吨悍、運(yùn)行命令后出現(xiàn),如下:
3蹋嵌、點(diǎn)擊 “Window->Open Perspective” 育瓜。如圖:
4、按第三步操作完以后栽烂,出現(xiàn)如下:
5躏仇、選擇“hieararchyviewer ”,點(diǎn)擊“OK” 即可愕鼓,如下:
如何在真機(jī)上正常使用Hierarchy View
Hierarchy Viewer
如果不進(jìn)行 “特殊” 配置的話是無法連接真機(jī)钙态,會(huì)報(bào)以下錯(cuò)誤:
[hierarchyviewer]Unable to get view server version from device XXXXX
[hierarchyviewer]Unable to get view server protocol version from device XXXXXX
[ViewServerDevice]Unable to debug device: XXXXX
[hierarchyviewer]Missing forwarded port for XXXXX
[hierarchyviewer]Unable to get the focused window from device XXXXX
無法連接真機(jī)的原因是:To preserve security, Hierarchy Viewer can only connect to devices running a developer version of the Android system.
出于安全性考慮, Hierarchy Viewe
只能連接開發(fā)版手機(jī)或模擬器菇晃。
Android 源碼實(shí)現(xiàn)這一限制的地方在 /frameworks/base/services/core/java/com/android/server/wm/WindowManageService.java :
檢驗(yàn)一臺(tái)手機(jī)/模擬器是否開啟了View Server
的辦法是:
adb shell service call window 3
若返回值是:Result: Parcel(00000000 00000000 '........')" 說明View Server處于關(guān)閉狀態(tài)
若返回值是:Result: Parcel(00000000 00000001 '........')" 說明View Server處于開啟狀態(tài)
有時(shí)碰到模擬器或開發(fā)發(fā)版手機(jī)册倒,view Hierarchy
還是無法連接,可以先使用以上方法檢查一下View Server
狀態(tài)磺送。如果沒有開啟驻子,則使用以下命令打開View Server
:
adb shell service call window 1 i32 4939
也可以使用使用以下命令關(guān)閉View Server:
adb shell service call window 2 i32 4939
那么如何在真機(jī)能夠正常使用Hierarchy Viewer
呢?這里總結(jié)了以下幾個(gè)方法:
方法一:
配置設(shè)備估灿,打開手機(jī)的開發(fā)者選項(xiàng)崇呵。
如果你的手機(jī)是 android 4.0 或者以下,請(qǐng)根據(jù)開源項(xiàng)目 View Server(https://github.com/romainguy/ViewServer) 進(jìn)行安裝和配置馅袁。
如果你的手機(jī)是4.1或以上域慷,則必須進(jìn)行以下環(huán)境變量配置:
點(diǎn)擊 計(jì)算機(jī)屬性-》高級(jí)系統(tǒng)設(shè)置-》環(huán)境變量
新建環(huán)境變量
ANDROID_HVPROTO
, 并設(shè)置其值為ddm
,保存重啟
該方法參考 android 官方文檔《Device Setup for Hierachy Viewer》https://developer.android.com/studio/profile/hierarchy-viewer-setup.html
然而在親自試用真機(jī)(魅族MX4pro android 5.1 和 android 4.4的機(jī)頂盒)測(cè)試過程中犹褒,配置環(huán)境變量的方法似乎并沒有起到作用抵窒,還是連不上。
不過直接在調(diào)試 app 中集成 View Server 開源項(xiàng)目是沒有任何問題的叠骑。
方法二:
話說前面Hierarchy Viewer
只能連接 Android 開發(fā)版手機(jī)或是模擬器李皇,只有ro.secure==0 && ro.debuggable==1
的 Android 系統(tǒng)。ro.xxxx
這種句式是不是覺得有點(diǎn)熟悉宙枷?不就是 android 系統(tǒng)的/system/build.prop
文件中的配置樣式么掉房。推測(cè)如果將ro.secure==0 && ro.debuggable==1
這個(gè)兩個(gè)配置添加進(jìn)來應(yīng)該能夠起作用吧,于是進(jìn)行以下嘗試:
先把手機(jī)
root
在進(jìn)到在
/system/build.prop
中添加ro.secure==0
和ro.debuggable==1
慰丛, 保存配置并重啟手機(jī)卓囚,Hierarchy Viewer
連接正常,終于可以正常調(diào)試了璧帝。
好了捍岳,關(guān)于控件ID的獲取就分享到這里。希望大家都能熟練掌握睬隶。如果你對(duì)Python自動(dòng)化軟件測(cè)試感興趣可以加入我們扣裙一起學(xué)習(xí)175317069锣夹。有各項(xiàng)測(cè)試學(xué)習(xí)資源,也有行業(yè)深潛多年的技術(shù)人分析講解苏潜。
歡迎【點(diǎn)贊】银萍、【評(píng)論】、【關(guān)注】~
Time will tell.(時(shí)間會(huì)證明一切)