uiautomator测试框架,深入研究之setText(String)

来源:互联网 发布:机器人编程工资待遇 编辑:程序博客网 时间:2024/05/27 06:54

在android4.2.2中的setText(String text)与android4.3的方法,内部是有些不一样的。但是我们是要学就学最新的嘛,就研究一下4.3的。其实4.2.2的也差不多。

4.3的源码

    public boolean setText(String text) throws UiObjectNotFoundException {

      Tracer.trace(text);
        clearTextField();
        return getInteractionController().sendText(text);
    }

里面的clearTextField()的源码如下:

----------------------------------------------------------------------------------------------

    public void clearTextField() throws UiObjectNotFoundException {

        Tracer.trace();
        // 找需要点击的对象的NodeInfo
        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
        if(node == null) {
            throw new UiObjectNotFoundException(getSelector().toString());
        }
        Rect rect = getVisibleBounds(node);

// 长按聚焦
        getInteractionController().longTapNoSync(rect.left + 20, rect.centerY());
        UiObject selectAll = new UiObject(new UiSelector().descriptionContains("Select all"));
        if(selectAll.waitForExists(50))
            selectAll.click();
        // wait for the selection
        SystemClock.sleep(250);
        // delete it
        getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);
    }

从源码可以看出,他是先制造一个痕迹,然后再找到需要的节点,再得到他的坐标(x轴+20,y轴的中间值,xy坐标原点在屏幕的左上角),然后长按 (时间是系统设置的长按时间),之后 SystemClock.sleep(250),等待 全选 后,执行delete键,即删除。

----------------------------------------------------------------------------------------------------

之后执行sendText(),

    public boolean sendText(String text) {
        if (DEBUG) {
            Log.d(LOG_TAG, "sendText (" + text + ")");
        }


        KeyEvent[] events = mKeyCharacterMap.getEvents(text.toCharArray());


        if (events != null) {
            long keyDelay = Configurator.getInstance().getKeyInjectionDelay();
            for (KeyEvent event2 : events) {
                // We have to change the time of an event before injecting it because
                // all KeyEvents returned by KeyCharacterMap.getEvents() have the same
                // time stamp and the system rejects too old events. Hence, it is
                // possible for an event to become stale before it is injected if it
                // takes too long to inject the preceding ones.
                KeyEvent event = KeyEvent.changeTimeRepeat(event2,
                        SystemClock.uptimeMillis(), 0);
                if (!injectEventSync(event)) {
                    return false;
                }
                SystemClock.sleep(keyDelay);
            }
        }
        return true;
    }

他是完全模仿按键动作的。这里会有一个keyInjectionDelay(),就是插入俩个字母之间的时间间隔。最终完成字母插入动作。

所以,这里真正的setText(),执行的真正动作是,得到节点信息,再而得到节点的坐标,通过descriptionContains("Select all"),来全选,若没有则不能全选,之后点击,等250ms,执行删除键,再执行真正的按键输入动作,输入显示出你预先设定的输入内容(注意,该方法的输入方式是调用键盘的,所以一般能完成英文的输入,中文指定字符的输入会比较麻烦)。