UIAutomator2.0详解(UIDevice篇----waitForIdle)

来源:互联网 发布:react.js 官网 编辑:程序博客网 时间:2024/06/06 02:47

UIDevice提供了5个方法用于等待。本文我们将一一讲解。
先来看一下,如果没有wait操作,我们的执行效果会是怎样。
我们以之前章节(触屏操作3)中的示例,去除wait后,看一下效果。

修改后,代码如下

    int timeOut=1000;    @Test    public void FunctionKeyTest4(){        Log.i(TAG, "Start Test");//        mDevice.waitForIdle(timeOut);        int h=mDevice.getDisplayHeight();        int w=mDevice.getDisplayWidth();        int left=200;        int right=w-200;        int step=50;        Log.i(TAG, "left = "+left+" Right = "+right);        //(1)From Right to Left        Log.i(TAG, "from ("+right+","+h/2+") to ("+left+","+h/2+")");        result=mDevice.swipe(right, h/2, left, h/2, step);        Log.i(TAG, "Swipe result (Right to Left) = "+result);//        mDevice.waitForIdle(timeOut);        //(2)From Left to Right        Log.i(TAG, "from ("+left+","+h/2+") to ("+right+","+h/2+")");        result=mDevice.swipe(left, h/2, right, h/2, step);        Log.i(TAG, "Swipe result (Left to Right) = "+result);//        mDevice.waitForIdle(timeOut);        //(3)Click        result=mDevice.click(300, 1000);        Log.i(TAG, "Click = "+result);//        mDevice.waitForIdle(timeOut);    }

运行结果如下:

11-08 16:54:03.421 I/com.breakloop.u2demo.uidevice.FingerTest: Start Test11-08 16:54:03.422 I/com.breakloop.u2demo.uidevice.FingerTest: left = 200 Right = 88011-08 16:54:03.422 I/com.breakloop.u2demo.uidevice.FingerTest: from (880,906) to (200,906)11-08 16:54:04.414 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Right to Left) = true11-08 16:54:04.414 I/com.breakloop.u2demo.uidevice.FingerTest: from (200,906) to (880,906)11-08 16:54:05.260 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Left to Right) = true11-08 16:54:05.376 I/com.breakloop.u2demo.uidevice.FingerTest: Click = true

运行效果如图:

这里写图片描述

整个测试案例,包括三个动作:左滑,右滑和点击。从效果上看,第一个动作未做完,第二个动作便开始了。而最后的点击动作未完成,原因在于,点击时还处于滑动状态。log日志中显示的动作执行时间,也印证了以上说法。

按照官方文档中所说,每个step将会花费5毫秒,实例中step为50,因此理论上,250毫秒可以完成滑动动作。但从运行结果中看,花费接近1秒都没有完成滑动,因此step的5毫秒仅为理论值。各家的性能不同,消耗时间也就不同了。

至此,我们来找解决方案。还是列举一下UIDevice提供的5个方法
(1)public void waitForIdle()
(2)public void waitForIdle(long timeout)
(3)public boolean waitForWindowUpdate(final String packageName, long timeout)
(4)public R wait(SearchCondition condition, long timeout)
(5)public R performActionAndWait(Runnable action, EventCondition condition, long timeout)

注:所有方法的timeout皆为毫秒为单位。

先看一下方法(1),(2)

这里写图片描述

这里写图片描述

这里写图片描述

对比方法(1),(2),可以发现,方法(1)实质上是方法(2)的调用,传入TIMEOUT的值为10秒。因此,我们跳过方法(1)直接以方法(2)做为实验对象。

那么,问题又来了,如何判断Idle?
新Event与上一个Event之间的时间间隔大于某一固定的毫秒数,即视为Idle。我们可以根据源码,看到该固定值为500毫秒(见下图)。因此方法(2)的Timeout不能小于500,否则无效。

这里写图片描述

这里写图片描述

在每个动作后,添加代码,并将TimeOut设置为550毫秒。

mDevice.waitForIdle(timeOut);//timeOut=550

我们看一下效果。

这里写图片描述

执行结果如下:

11-08 18:29:22.136 I/com.breakloop.u2demo.uidevice.FingerTest: Start Test11-08 18:29:22.633 I/com.breakloop.u2demo.uidevice.FingerTest: left = 200 Right = 88011-08 18:29:22.634 I/com.breakloop.u2demo.uidevice.FingerTest: from (880,906) to (200,906)11-08 18:29:23.708 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Right to Left) = true11-08 18:29:24.588 W/UiAutomatorBridge: Could not detect idle state.                                        java.util.concurrent.TimeoutException: No idle state with idle timeout: 500 within global timeout: 55011-08 18:29:24.588 I/com.breakloop.u2demo.uidevice.FingerTest: from (200,906) to (880,906)11-08 18:29:25.405 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Left to Right) = true11-08 18:29:26.263 W/UiAutomatorBridge: Could not detect idle state.                                        java.util.concurrent.TimeoutException: No idle state with idle timeout: 500 within global timeout: 55011-08 18:29:26.263 I/com.breakloop.u2demo.uidevice.FingerTest: Click(300,1000)11-08 18:29:26.381 I/com.breakloop.u2demo.uidevice.FingerTest: Click = true

从日志中,我们可以发现两个结论
(1)waitforidle抛出了异常TimeoutException。可见在550毫秒内,没有出现Idle,也就是说滑动操作至少在等待的550毫秒内,没能完成。
(2)抛出异常后,系统又进行了等待,等待滑动操作完整完成后,才开始了下一个动作。
为了证明结论(2),我们将step调整至200,这样可以有足够的时间来观察滑动动作的完成。

执行结果如下

11-08 18:42:18.055 I/com.breakloop.u2demo.uidevice.FingerTest: Start Test11-08 18:42:18.621 W/UiAutomatorBridge: Could not detect idle state.                                        java.util.concurrent.TimeoutException: No idle state with idle timeout: 500 within global timeout: 55011-08 18:42:18.623 I/com.breakloop.u2demo.uidevice.FingerTest: left = 200 Right = 88011-08 18:42:18.623 I/com.breakloop.u2demo.uidevice.FingerTest: from (880,906) to (200,906)11-08 18:42:22.671 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Right to Left) = true11-08 18:42:23.657 W/UiAutomatorBridge: Could not detect idle state.                                        java.util.concurrent.TimeoutException: No idle state with idle timeout: 500 within global timeout: 55011-08 18:42:23.657 I/com.breakloop.u2demo.uidevice.FingerTest: from (200,906) to (880,906)11-08 18:42:26.980 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Left to Right) = true11-08 18:42:27.669 W/UiAutomatorBridge: Could not detect idle state.                                        java.util.concurrent.TimeoutException: No idle state with idle timeout: 500 within global timeout: 55011-08 18:42:27.669 I/com.breakloop.u2demo.uidevice.FingerTest: Click(300,1000)11-08 18:42:27.783 I/com.breakloop.u2demo.uidevice.FingerTest: Click = true

执行效果如下图:

这里写图片描述

那么问题又来了~
如果在waitForIdle抛出异常前完成动作呢?
这次我们将Timeout设置为10s,Step改回50。

执行结果如下:

11-08 19:03:32.660 I/com.breakloop.u2demo.uidevice.FingerTest: Start Test11-08 19:03:34.530 I/com.breakloop.u2demo.uidevice.FingerTest: left = 200 Right = 88011-08 19:03:34.530 I/com.breakloop.u2demo.uidevice.FingerTest: from (880,906) to (200,906)11-08 19:03:35.346 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Right to Left) = true11-08 19:03:36.534 I/com.breakloop.u2demo.uidevice.FingerTest: from (200,906) to (880,906)11-08 19:03:37.365 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Left to Right) = true11-08 19:03:38.539 I/com.breakloop.u2demo.uidevice.FingerTest: Click(300,1000)11-08 19:03:38.653 I/com.breakloop.u2demo.uidevice.FingerTest: Click = true

执行效果如图:

这里写图片描述

可以看到每个动作都很从容的完成,并且没有抛出异常。

因此,对于waitForIdle总结如下。
(1)如果timeout内,未能完成动作,抛出异常,但等待动作完成。
(2)如果timeout内,完成动作,不抛异常,之后执行接下来的动作。
(3)timeout必须大于500ms,否则无意义。

由于不想让博文显得冗长,将在之后的篇幅中演示另外三个方法的使用。

waitForWindowUpdate方法,可参见
http://blog.csdn.net/daihuimaozideren/article/details/78482463

原创粉丝点击