上一篇文章《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 扫描码: |