簡介
在前邊的第二十二篇文章里,已經分享了通過獲取控件的坐標點來獲取點擊事件的所需要的點擊位置,那么還有沒有其他方法來獲取控件點擊事件所需要的點擊位置呢?答案是:Yes!因為在不同的大小屏幕的手機上獲取控件的坐標點,不是一樣的,而是有變化的,因此在不同的手機機型上,我們可能都需要重新獲取坐標點,這么操作起來,如果操作控件特別的多,那么獲取控件的坐標點就會顯得特別的繁瑣。因此我們可以通過獲取控件的ID來避免獲取控件坐標點的這種弊端。
通過控件ID實現自動化腳本的運行,就性能而言,會比控件坐標的實現差一些;但是對于不同分辨率的設備都通用,不需要動態變換坐標。控件ID的獲取主要是通過HierarchyViewer。下面就HierarchyViewer從打開方式和使用兩方面進行講解。
HierarchyViewer的打開方式
HierarchyViewer的打開方式有兩種:一種是eclipse中打開HierarchyView視圖,另外一種是命令行中執行sdk/tools/hierarchyviewer.bat。
HierarchyViewer默認只能在非加密設備使用,例如工程機,工程平板或者模擬器。如果要在手機上使用HierarchyViewer,你需要在你的應用中添加一個開源庫View Server。鏈接地址:https://github.com/romainguy/ViewServer。該篇文章中有講解如何啟動真機View Server,大家如果有興趣,可參考:https://dup2.org/node/1538。
方式一:
連接您的真機設備,或打開模擬器,在eclipse中, 依次選擇Window-Open Perspective-Other,在Other中,選擇HierarchyView視圖,即可打開。
?
方式二:
連接您的真機設備或打開模擬器,運行cmd窗口,進入到sdk/tools目錄下,輸入命令hierarchyviewer.bat,運行hierarchyviewer。
? ?或者直接在sdk/tools目錄下,找到hierarchyviewer.bat,雙擊運行。
未開啟夜神模擬器的HierarchyViewer,如下圖:
開啟夜神模擬器后的HierarchyViewer,如下圖:
那么接下來看一下今天的重頭戲:講解利用HierarchyViewer獲取控件ID的方法。
HierarchyViewer獲取控件ID
HierarchyViewer啟動后,首先會看到的第一個窗口顯示了設備和模擬器的列表。點擊左邊的箭頭,就會展開當前設備或模擬器的Activity對象列表。列表中顯示了設備或模擬器上,UI當前可視的所有Activity對象。這些對象按照它們的Android組件名稱列出來。列表中的內容包含應用的Activity對象和系統的Activity對象。
當模擬器activity畫面變更后,點擊refresh可以加載新的頁面布局信息。
從列表中選擇你的activity名稱,雙擊,或點擊菜單欄的Load View Hierarchy按鈕,進入View Hierarchy窗口,查看它的view層次結構;或者點擊Inspect Screenshot按鈕,進入Pixel Perfect窗口,從而查看UI的一個放大圖像。我們這里點擊進入View Hierarchy窗口。
可以從下圖中看到模擬器此activity的畫面布局信息,左邊部分是hierarchy通過樹形結構展示的布局形式,右下角是模擬器上當前頁面的UI布局信息。
通過滾動鼠標,可以放大每個樹節點;拖拽鼠標,移動樹形結構布局。雙擊樹節點可以展示單獨的UI部分。從下圖中,可以看到,id/btn_login即為登錄按鈕的ID。依次類推,可以查看其它控件ID。
注:對于列表、或者彈出框則無法直接通過點擊ID操作成功,需要計算ID的坐標。
控件ID之Monkeyrunner腳本演示
? ? 同樣的,我們將下面一段Monkeyrunner腳本寫到一個test.py文件中,然后運行test.py文件,查看模擬器上是不是做相應的操作。
1 # coding=utf- 8 2 # 1 .先設置編碼,utf- 8可支持中英文,如上,一般放在第一行 3 4 # 2 .注釋:包括記錄創建時間,創建人,項目名稱。 5 ''' 6 Created on 2019 - 7 - 30 7 @author: 北京-宏哥 QQ交流群: 707699217 8 Project:學習和使用appium自動化測試- 獲取控件的ID 9 ''' 10 # 3 .導入模塊 11 12 from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice 13 14 from com.android.monkeyrunner.easy import EasyMonkeyDevice #提供了根據ID進行訪問 15 16 from com.android.monkeyrunner.easy import By #根據ID返回PyObject的方法 17 18 device= MonkeyRunner.waitForConnection() 19 20 #啟動activity(這里啟動qq) 21 22 device.startActivity(component= " com.tencent.mobileqq/.activity.SplashActivity " ) 23 24 easy_device= EasyMonkeyDevice(device) #必須在activity啟動之后 25 26 #登錄界面,點擊賬號輸入框 27 28 easy_device.touch(By.id( ' id/0x20e ' ),MonkeyDevice.DOWN_AND_UP) 29 30 device.type( '1918991791 ' ) #輸入qq賬號
至此,獲取控件ID的方式已經介紹完,由于沒有深入研究,肯定有不少功能點沒有介紹到,有時間的話再做完善。
控件ID不存在或重復
我們在用monkeyrunner進行Android自動化時,通過獲取坐標點或控件ID進行一系列操作。由于使用坐標點時,屏幕分辨率一旦更改,則代碼中用到坐標的地方都要修改,這樣導致代碼的復用率較低。因此,我們多采用控件ID操作(注:控件ID需要在模擬器中使用,對于絕大多數真機不適用)。但是,某些控件的ID是不存在的或重復存在,那么,遇到這種情況,我們怎樣繼續使用控件ID進行自動化測呢?
例如,下圖中,我想要獲取最右側紅框中的id/tv,但是,大家會發現,和它并列的也有重復的控件id值。現在我們就講述一下這種情況(控件ID不存在同樣處理)。
我們從這個控件樹的節點角度來思考如何獲得控件的引用。我們可以看到在上圖hierarchy viewer中的每個控件所對應的框形中,右下角都有一個數字。其實這個數字就是該控件在同級兄弟節點中的索引值,我們知道這個索引值后,就可以根據parentView.children[index]屬性來獲取任意父節點所對應的子節點的對象引用。其中的parentView可以是樹形圖中有效ID的任意父節點(父節點要保證唯一有效),然后利用python函數的可變參數列表特性來傳入所需控件的索引列表即可構造出得到任意節點引用的字符串,從而得到其引用。
核心代碼如下,把如下代碼加入自己的python腳本中,直接調用該函數即可。
1 #定義獲取重復或不存在控件id,尋找子節點函數 2 def getChildView(parentId, * childSeq): 3 hierarchyViewer = device.getHierarchyViewer() 4 childView= " hierarchyViewer.findViewById(' " + parentId + " ') " 5 for index in childSeq: 6 childView += ( ' .children[ ' + str(index) + ' ] ' ) 7 print childView 8 return eval(childView) 9 10 #獲取id的文本 11 def getText(view): 12 if view != None: 13 return (view.namedProperties. get ( ' text:mText ' ).value)
有了以上代碼之后,我們可以獲取上圖中的id/tv,方法如下:
1 getChildView( ' id/province_list ' , 5 , 0 , 0 )
其中結合上圖可知,getChildView的第一個參數即:有效且唯一的父節點
參數二、三依次為要獲取的控件ID的父節點的父節點
注:用到的父節點即圖中的id/province_list,有效且唯一的值。當前的父節點右下角的角標,不需要在getChildView函數中顯示。
這樣,通過以上函數,再結合Hierarchyviewer圖形,我們獲取到了重復的控件ID。
由于Hierarchyviewer看起來不是特別方便,這里再推薦一款和Hierarchyviewer類似功能的工具:uiautomatorviewer(存儲在sdk\tools中,雙擊打開即可)
由上圖中,uiautomatorviewer每個控件前面的數字即相當于Hierarchyviewer的角標,我們同樣可以獲取到目標ID的最終有效且唯一的父節點,從而調用函數getChildView('id/province_list',5,0,0)
獲取到了不存在或重復的控件ID后,我們可以通過其坐標,進行點擊操作。
首先,定義一個“獲取指定按鈕坐標”的函數
1 def getBtnPoint(btn): 2 print btn 3 point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn); 4 return point
然后我們可以通過坐標,實現點擊操作,例如:
1 askView = getChildView( ' id/tabs ' , 1 ) 2 askPpoint = getBtnPoint(askView) 3 device.touch(askPpoint.x,askPpoint.y, ' DOWN_AND_UP ' )
至此,我們介紹完了處理控件ID不存在或重復時的方法,有興趣的小伙伴或者童鞋們可以自己動手實踐一把,就會更能體會Hierarchyviewer/uiautomatorviewer+getChildView()獲取不存在或重復控件ID的用法、樂趣及其奧秘。
小結
一、直接在
sdk>tools
下面找到
hierarchyviewer.bat
雙擊運行,然后運行成功了。
但是出現這個提示:
The standalone version of hieararchyviewer is deprecated.
Please use Android Device Monitor (tools/monitor.bat) instead.
大概意思是說,單獨版本的?
hieararchyviewer
?已經被棄用了。請使用?
Android Device Monitor
來代替。
Android Device Monitor
在
tools
目錄下面找到
monitor.bat
即可。
為了緊跟時代潮流,就決定用 Android Device Monitor 啟動即可。
具體操作啟動步驟:
1、運行命令monitor.bat,如下圖
2、運行命令后出現,如下圖的界面
3、點擊“Window->Open Perspective”。如圖
4、按第三步操作完以后,出現如下圖:
5、選擇“ hieararchyviewer ?”,點擊“OK”,即可,如下圖
?二、如何在真機上正常使用Hierarchy View
? ?Hierarchy Viewer如果不進行“特殊”配置的話是無法連接真機,會報以下錯誤:
[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
無法連接真機的原因是:To preserve security, Hierarchy Viewer can only connect to devices running a developer version of the Android system.出于安全性考慮, Hierarchy Viewe 只能連接開發版手機或模擬器。
? ?Android源碼實現這一限制的地方在/frameworks/base/services/core/java/com/android/server/wm/WindowManageService.java:

檢驗一臺手機/模擬器是否開啟了View Server的辦法是:
adb shell service call window 3
若返回值是:Result: Parcel(00000000 00000000 '........')" 說明View Server處于關閉狀態
若返回值是:Result: Parcel(00000000 00000001 '........')" 說明View Server處于開啟狀態
有時碰到模擬器或開發發版手機, view Hierarchy 還是無法連接,可以先使用以上方法檢查一下View Server狀態。如果沒有開啟,則使用以下命令打開View Server:
adb shell service call window 1 i32 4939
也可以使用使用以下命令關閉View Server:
adb shell service call window 2 i32 4939
那么如何在真機能夠正常使用Hierarchy Viewer了?通過實踐目前總結了以下三種方法:
方法一。
1,配置設備,打開手機的開發者選項
如果你的手機是android 4。0 或者以下,請根據開源項目 View ?Server(https://github.com/romainguy/ViewServer) 進行安裝和配置
如果你的手機是4.1或以上,則必須進行以下環境變量配置:
1.點擊 計算機屬性-》高級系統設置-》環境變量
2.新建環境變量ANDROID_HVPROTO, 并設置其值為 ddm, 保存重啟
PS: 該方法參考android 官方文檔《Device Setup for Hierachy Viewer》https://developer.android.com/studio/profile/hierarchy-viewer-setup.html
然而在本人親自試用真機(魅族MX4pro android 5.1 和 android 4.4的機頂盒)測試過程中,配置環境變量的方法似乎并沒有起到作用,還是連不上。
不過直接在調試app中集成View Server開源項目是沒有任何問題的。
方法二:
話說前面Hierarchy Viewer只能連接Android開發版手機或是模擬器,只有ro.secure==0 && ro.debuggable==1的Android系統(這一句是其他網友的文章看到的,沒有在android 官方查證到 )。ro.xxxx這種句式大家是不是覺得有點熟悉?不就是android系統的 /system/build.prop文件中的配置樣式么。推測如果將ro.secure==0 && ro.debuggable==1這個兩個配置添加進來應該能夠起作用吧,于是進行以下嘗試:
1.先把手機root
2.在進到在/system/build.prop 中添加ro.secure==0? 和 ro.debuggable==1, 保存配置并重啟手機,Hierarchy Viewer連接正常,終于可以正常調試了。
方法三:
參照《如何在Root的手機上開啟ViewServer,使得HierachyViewer能夠連接》http://maider.blog.sohu.com/255448342.html。該方法本人沒有實踐過,一看有18個步驟,
還涉及到 android逆向、smail,瞬間腦仁發緊,有興趣的同學可以自行嘗試一下。
三、好了,關于控件ID的獲取,就分享到這里。
您的肯定就是我進步的動力。
如果你感覺還不錯,就請鼓勵一下吧!記得點波
?
推薦
?
哦!!!(點擊右邊的小球即可,膽子大的可以嘗試一下哦!?
:)
)
個人公眾號
微信群
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
