您好,登錄后才能下訂單哦!
根據上一篇文章《UiAutomator源碼分析之注入事件》開始時提到的計劃,這一篇文章我們要分析的是第二點:
UiObject appsTab = new UiObject(new UiSelector().text("Apps")); appsTab.click()那么這個過程發生了什么呢?這就是我們接下來要說的事情了。
在我沒有去分析uiautomator的源代碼之前,我一直以為空間查找是在通過UiSelector初始化一個UiObject的時候發生的:
UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click()我們進入到代表一個控件的UiObject對應的操作控件的方法去看下就清楚了,以上面的click為例:
/* */ public boolean click() /* */ throws UiObjectNotFoundException /* */ { /* 389 */ Tracer.trace(new Object[0]); /* 390 */ AccessibilityNodeInfo node = findAccessibilityNodeInfo(this.mConfig.getWaitForSelectorTimeout()); /* 391 */ if (node == null) { /* 392 */ throw new UiObjectNotFoundException(getSelector().toString()); /* */ } /* 394 */ Rect rect = getVisibleBounds(node); /* 395 */ return getInteractionController().clickAndSync(rect.centerX(), rect.centerY(), this.mConfig.getActionAcknowledgmentTimeout()); /* */ }正式290行的調用觸發uiautomator去調用UiAutomation去獲取到我們想要的控件節點AccessibilityNodeInfo信息的。
下面我們看下uiautomator是怎么去獲取到代表窗口所有控件的根的Root Node的,我們進入UiObject的findAccessibilityNodeInfo這個方法:
/* */ protected AccessibilityNodeInfo findAccessibilityNodeInfo(long timeout) /* */ { /* 164 */ AccessibilityNodeInfo node = null; /* 165 */ long startMills = SystemClock.uptimeMillis(); /* 166 */ long currentMills = 0L; /* 167 */ while (currentMills <= timeout) { /* 168 */ node = getQueryController().findAccessibilityNodeInfo(getSelector()); /* 169 */ if (node != null) { /* */ break; /* */ } /* */ /* 173 */ UiDevice.getInstance().runWatchers(); /* */ /* 175 */ currentMills = SystemClock.uptimeMillis() - startMills; /* 176 */ if (timeout > 0L) { /* 177 */ SystemClock.sleep(1000L); /* */ } /* */ } /* 180 */ return node; /* */ }UiObject對象會首先去獲得一個QueryController對象,然后調用該對象的findAccessibilityNodeInfo同名方法:
/* */ protected AccessibilityNodeInfo findAccessibilityNodeInfo(UiSelector selector, boolean isCounting) /* */ { /* 143 */ this.mUiAutomatorBridge.waitForIdle(); /* 144 */ initializeNewSearch(); /* */ /* 146 */ if (DEBUG) { /* 147 */ Log.d(LOG_TAG, "Searching: " + selector); /* */ } /* 149 */ synchronized (this.mLock) { /* 150 */ AccessibilityNodeInfo rootNode = getRootNode(); /* 151 */ if (rootNode == null) { /* 152 */ Log.e(LOG_TAG, "Cannot proceed when root node is null. Aborted search"); /* 153 */ return null; /* */ } /* */ /* */ /* 157 */ UiSelector uiSelector = new UiSelector(selector); /* 158 */ return translateCompoundSelector(uiSelector, rootNode, isCounting); /* */ } /* */ }這里做了兩個重要的事情:
/* */ protected AccessibilityNodeInfo getRootNode() /* */ { /* 168 */ int maxRetry = 4; /* 169 */ long waitInterval = 250L; /* 170 */ AccessibilityNodeInfo rootNode = null; /* 171 */ for (int x = 0; x < 4; x++) { /* 172 */ rootNode = this.mUiAutomatorBridge.getRootInActiveWindow(); /* 173 */ if (rootNode != null) { /* 174 */ return rootNode; /* */ } /* 176 */ if (x < 3) { /* 177 */ Log.e(LOG_TAG, "Got null root node from accessibility - Retrying..."); /* 178 */ SystemClock.sleep(250L); /* */ } /* */ } /* 181 */ return rootNode; /* */ }172調用的是UiAutomatorBridge對象的方法,通過我們上面的幾篇文章我們知道UiAutomatorBridge提供的方法大部分都是直接調用UiAutomation的方法的,我們進去看看是否如此:
/* */ public AccessibilityNodeInfo getRootInActiveWindow() { /* 66 */ return this.mUiAutomation.getRootInActiveWindow(); /* */ }果不其然,最終簡單明了的直接調用UiAutomation的getRootInActiveWindow來獲得根AccessibilityNodeInfo.
/* */ public boolean click() /* */ throws UiObjectNotFoundException /* */ { /* 389 */ Tracer.trace(new Object[0]); /* 390 */ AccessibilityNodeInfo node = findAccessibilityNodeInfo(this.mConfig.getWaitForSelectorTimeout()); /* 391 */ if (node == null) { /* 392 */ throw new UiObjectNotFoundException(getSelector().toString()); /* */ } /* 394 */ Rect rect = getVisibleBounds(node); /* 395 */ return getInteractionController().clickAndSync(rect.centerX(), rect.centerY(), this.mConfig.getActionAcknowledgmentTimeout()); /* */ }從395行可以看到,最終還是把控件節點的信息轉換成控件的坐標點進行點擊的,至于怎么點擊,大家可以參照上一篇文章,無非就是通過建立一個runnable的線程進行點擊事件的注入了
作者 | 自主博客 | 微信 | CSDN |
天地會珠海分舵 | http://techgogogo.com | 服務號:TechGoGoGo 掃描碼:
| 向AI問一下細節 免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。 猜你喜歡最新資訊相關推薦
相關標簽AI
助 手
洪泽县|
平湖市|
丁青县|
哈尔滨市|
玛纳斯县|
青海省|
武鸣县|
南城县|
漳州市|
集安市|
正蓝旗|
两当县|
黄龙县|
龙游县|
彩票|
陵水|
梁平县|
双辽市|
维西|
鄂伦春自治旗|
额济纳旗|
台中县|
石首市|
彭阳县|
洛阳市|
理塘县|
南投市|
宁武县|
鞍山市|
闽清县|
青州市|
大新县|
涞源县|
西丰县|
绿春县|
灌阳县|
林甸县|
阜新|
临沭县|
井研县|
淅川县|
|