android自动化测试Uiautomator API分析之二
来源:互联网 发布:ssm会员管理系统源码 编辑:程序博客网 时间:2024/06/05 17:23
对控件的操作,主要在UiObject中。例如各种点击事件。
以长按事件来论述详细的流程。
UiObject的longClick方法如下,
public boolean longClick() throws UiObjectNotFoundException { Tracer.trace(); AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout()); if(node == null) { throw new UiObjectNotFoundException(getSelector().toString()); } Rect rect = getVisibleBounds(node); return getInteractionController().longTapNoSync(rect.centerX(), rect.centerY()); }
首先调用findAccessibilityNodeInfo方法在当前屏幕重新查找该控件,
然后调用InteractionController 的longTapNoSync方法写入事件。
1.1 findAccessibilityNodeInfo
protected AccessibilityNodeInfo findAccessibilityNodeInfo(long timeout) { AccessibilityNodeInfo node = null; long startMills = SystemClock.uptimeMillis(); long currentMills = 0; while (currentMills <= timeout) { node = getQueryController().findAccessibilityNodeInfo(getSelector()); if (node != null) { break; } else { // does nothing if we're reentering another runWatchers() UiDevice.getInstance().runWatchers(); } currentMills = SystemClock.uptimeMillis() - startMills; if(timeout > 0) { SystemClock.sleep(WAIT_FOR_SELECTOR_POLL); } } return node; }
getQueryController方法返回的是QueryController对象,然后调用findAccessibilityNodeInfo,
public AccessibilityNodeInfo findAccessibilityNodeInfo(UiSelector selector) { return findAccessibilityNodeInfo(selector, false); } protected AccessibilityNodeInfo findAccessibilityNodeInfo(UiSelector selector, boolean isCounting) { mUiAutomatorBridge.waitForIdle(); initializeNewSearch(); if (DEBUG) Log.d(LOG_TAG, "Searching: " + selector); synchronized (mLock) { AccessibilityNodeInfo rootNode = getRootNode(); if (rootNode == null) { Log.e(LOG_TAG, "Cannot proceed when root node is null. Aborted search"); return null; } // Copy so that we don't modify the original's sub selectors UiSelector uiSelector = new UiSelector(selector); return translateCompoundSelector(uiSelector, rootNode, isCounting); } }
首先调用getRootNode来获得根节点,
然后调用translateCompoundSelector来根据用户指定的UiSelector格式从上面获得根节点开始遍历窗口控件树,以获得目标控件。
1.1.1 getRootNode
getRootNode方法如下,
protected AccessibilityNodeInfo getRootNode() { final int maxRetry = 4; final long waitInterval = 250; AccessibilityNodeInfo rootNode = null; for(int x = 0; x < maxRetry; x++) { rootNode = mUiAutomatorBridge.getRootInActiveWindow(); if (rootNode != null) { return rootNode; } if(x < maxRetry - 1) { Log.e(LOG_TAG, "Got null root node from accessibility - Retrying..."); SystemClock.sleep(waitInterval); } } return rootNode;}
调用UiAutomatorBridge 的getRootInActiveWindow方法,
public AccessibilityNodeInfo getRootInActiveWindow() { return mUiAutomation.getRootInActiveWindow(); }
直接调用UiAutomation的getRootInActiveWindow方法,
public AccessibilityNodeInfo getRootInActiveWindow() { final int connectionId; synchronized (mLock) { throwIfNotConnectedLocked(); connectionId = mConnectionId; } // Calling out without a lock held. return AccessibilityInteractionClient.getInstance() .getRootInActiveWindow(connectionId); }
很明显调用AccessibilityInteractionClient的getRootInActiveWindow方法,
AccessibilityInteractionClient是framework中的类,在此就不论述了。
1.1.2 translateCompoundSelector
translateCompoundSelector方法如下,
private AccessibilityNodeInfo translateCompoundSelector(UiSelector selector, AccessibilityNodeInfo fromNode, boolean isCounting) { // Start translating compound selectors by translating the regular_selector first // The regular_selector is then used as a container for any optional pattern_selectors // that may or may not be specified. if(selector.hasContainerSelector()) // nested pattern selectors if(selector.getContainerSelector().hasContainerSelector()) { fromNode = translateCompoundSelector( selector.getContainerSelector(), fromNode, false); initializeNewSearch(); } else fromNode = translateReqularSelector(selector.getContainerSelector(), fromNode); else fromNode = translateReqularSelector(selector, fromNode); if(fromNode == null) { if (DEBUG) Log.d(LOG_TAG, "Container selector not found: " + selector.dumpToString(false)); return null; } if(selector.hasPatternSelector()) { fromNode = translatePatternSelector(selector.getPatternSelector(), fromNode, isCounting); if (isCounting) { Log.i(LOG_TAG, String.format( "Counted %d instances of: %s", mPatternCounter, selector)); return null; } else { if(fromNode == null) { if (DEBUG) Log.d(LOG_TAG, "Pattern selector not found: " + selector.dumpToString(false)); return null; } } } // translate any additions to the selector that may have been added by tests // with getChild(By selector) after a container and pattern selectors if(selector.hasContainerSelector() || selector.hasPatternSelector()) { if(selector.hasChildSelector() || selector.hasParentSelector()) fromNode = translateReqularSelector(selector, fromNode); } if(fromNode == null) { if (DEBUG) Log.d(LOG_TAG, "Object Not Found for selector " + selector); return null; } Log.i(LOG_TAG, String.format("Matched selector: %s <<==>> [%s]", selector, fromNode)); return fromNode; }
循环嵌套调用,获取目标控件。
1.2 longTapNoSync
InteractionController的longTapNoSync方法如下,
public boolean longTapNoSync(int x, int y) { if (DEBUG) { Log.d(LOG_TAG, "longTapNoSync (" + x + ", " + y + ")"); } if (touchDown(x, y)) { SystemClock.sleep(mUiAutomatorBridge.getSystemLongPressTime()); if(touchUp(x, y)) { return true; } } return false; }
两个方法touchDown和touchUp方法。touchDown方法如下,
private boolean touchDown(int x, int y) { if (DEBUG) { Log.d(LOG_TAG, "touchDown (" + x + ", " + y + ")"); } mDownTime = SystemClock.uptimeMillis(); MotionEvent event = MotionEvent.obtain( mDownTime, mDownTime, MotionEvent.ACTION_DOWN, x, y, 1); event.setSource(InputDevice.SOURCE_TOUCHSCREEN); return injectEventSync(event); }
首先构造一个MotionEvent对象,然后调用injectEventSync方法向系统注入该事件。
private boolean injectEventSync(InputEvent event) { return mUiAutomatorBridge.injectInputEvent(event, true); }
当然依次调用UiAutomatorBridge,UiAutomation
最后在UiAutomationConnection的injectInputEvent方法中完成实际的操作。
- android自动化测试Uiautomator API分析之二
- android自动化测试Uiautomator API分析之一
- android自动化测试Uiautomator源码分析之二
- android自动化测试之Uiautomator-UiDevice-API
- Android自动化测试之 Uiautomator-UiDevice-API
- Android自动化测试之UIAutomator
- Android自动化测试之UIAutomator
- android自动化测试Uiautomator源码分析之三
- android自动化测试Uiautomator源码分析之四
- android自动化测试Uiautomator源码分析之五
- android自动化测试Uiautomator源码分析之一
- Android自动化测试之UIAutomator(一)
- Android自动化测试之UIAutomator(一)
- Android自动化测试UiAutomator之环境配置
- 自动化测试之uiautomator
- android uiautomator自动化测试
- UiAutomator android自动化测试
- Android-自动化测试UIAutomator
- Git版本管理之旅(三)—— Git分支策略与管理
- C#触摸屏点击测试
- 排序算法二:二分法插入排序
- 4819: [Sdoi2017]新生舞会
- Unix环境高级编程读书笔记(4)
- android自动化测试Uiautomator API分析之二
- nginx屏蔽指定接口(URL)
- java jdk动态代理
- Java 版本控制工具-Git 学习总结
- PAT 1129Recommendation System
- Snowflake Snow Snowflakes
- python logging使用
- Android 中ListView悬浮头部效果设置
- 函数的可重入和不可重入