上一篇文章《UIAutomator源代碼分析之啓動和執行》咱們描寫敘述了uitautomator從命令行執行到載入測試用例執行測試的整個流程。過程當中咱們也描寫敘述了UiAutomatorBridge這個類的重要性,說它至關於UiAutomation的代理(咱們都知道UiAutomator是經過UiAutomation和AccessibilityService進行鏈接而後獲取界面空間信息和注入事件的).那麼今天開始咱們就環繞這個類以及跟它有關係的類進行進一步的分析。java
這一章節咱們會先看UiAutomatorBridge的整體框架,日後我會編寫其它文章經過一些詳細的樣例把它們串起來。因爲個人mackbook pro上沒有安裝類圖軟件,所下面圖是手畫的node
往下咱們就去初步描寫敘述下UiAutomatorBridge跟每一個相關的類的關係。android
UiAutomatorBridge擁有一個UiAutomation的成員變量,它們是聚合的關係,注意不是組合,因爲UiAutomation不必定僅僅能依賴UiAutomatorBridge而存在,咱們上一章節的UiAutomatorTestRunner就擁有一個UiAutomation的成員變量。微信
一旦UiAutomator工具需要經過UiAutomatorBridge獲取界面或者注入事件的時候。就會調用該成員變量.比方如下這個很是關鍵的去獲取當前界面的Root Node的方法:app
/* */ public AccessibilityNodeInfo getRootInActiveWindow() { /* 66 */ return this.mUiAutomation.getRootInActiveWindow(); /* */ }
QueryController作的所有事情就是去把UiSelector這個UI控件選擇子翻譯成真實的適合咱們使用的android.view.accessibility.AccessibilityNodeInfo。框架
UiAutomatorBridge擁有一個成員變量mQueryController保存了QueryController的一個實例:工具
/* */ private final QueryController mQueryController; /* */當UiObject需要獲取一個UiSelector指定的控件信息時,會去調用UiAutomatorBridge的getQueryController方法來得到這個mQueryController對象來進行對應的操做。例如如下面的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; /* */ }
該getQueryController方法會去調用UiAutomatorBridge的getQueryController方法:
ui
/* */ QueryController getQueryController() /* */ { /* 100 */ return UiDevice.getInstance().getAutomatorBridge().getQueryController(); /* */ }從上面的類圖咱們可以看到,除了UiAutomatorBridge會調用QueryController作事情外,QueryController又會反過來調用UiAutomatorBridge來作事情,因爲如圖所描寫敘述的,僅僅有UiAutomatorBridge擁有UiAutomation的實例,因此QueryController會持有一個UiAutomatorBridge的實例:
/* */ private final UiAutomatorBridge mUiAutomatorBridge;而後在需要的時候再調用UiAutomatorBridge,如如下的得到Root Node的方法:
/* */ 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; /* */ }
waitForIdle : 經過UiAutomation睡眠指定時間this
executeCommandAndWaitForAccessibilityEvent:經過UiAutomation運行指定線程的操做而後等待預期的時間返回
google
takeScreenshot :經過UiAutomation進行截圖
performGlobalAction : 經過UiAutomation去運行一些全局的動做。如打開近期打開過的app列表,回到home界面等
/* */ public boolean isScreenOn() /* */ { /* 111 */ IPowerManager pm = IPowerManager.Stub.asInterface(ServiceManager.getService("power")); /* */ /* 113 */ boolean ret = false; /* */ try { /* 115 */ ret = pm.isScreenOn(); /* */ } catch (RemoteException e) { /* 117 */ Log.e(LOG_TAG, "Error getting screen status", e); /* 118 */ throw new RuntimeException(e); /* */ } /* 120 */ return ret; /* */ }
做者 |
自主博客 |
微信 |
CSDN |
天地會珠海分舵 |
|
服務號:TechGoGoGo 掃描碼:
|