书接上文(waitForIdle),我们继续UIDevice的wait方式总结。本篇将着重讲说waitForWindowUpdate方法。
public boolean waitForWindowUpdate(final String packageName, long timeout)
我们还以上文滑动的测试案例为实验对象。这里只是将相应的waitForIdle换成waitForWindowUpdate方法。
修改后,代码如下:
String packageName="com.breakloop.test";
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);
result = mDevice.waitForWindowUpdate(packageName, timeOut);
Log.i(TAG, "wait For Window Update, result = " + result);
//(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);
result = mDevice.waitForWindowUpdate(packageName, timeOut);
Log.i(TAG, "wait For Window Update, result = " + result);
//(3)Click
Log.i(TAG, "Click(300,1000)");
result=mDevice.click(300, 1000);
Log.i(TAG, "Click = "+result);
result = mDevice.waitForWindowUpdate(packageName, timeOut);
Log.i(TAG, "wait For Window Update, result = " + result);
}
执行结果如下:
11-08 20:01:42.199 I/com.breakloop.u2demo.uidevice.FingerTest: Start Test
11-08 20:01:42.839 I/com.breakloop.u2demo.uidevice.FingerTest: left = 200 Right = 880
11-08 20:01:42.839 I/com.breakloop.u2demo.uidevice.FingerTest: from (880,906) to (200,906)
11-08 20:01:43.836 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Right to Left) = true
11-08 20:01:45.391 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = false
11-08 20:01:45.391 I/com.breakloop.u2demo.uidevice.FingerTest: from (200,906) to (880,906)
11-08 20:01:46.227 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Left to Right) = true
11-08 20:01:48.400 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = false
11-08 20:01:48.400 I/com.breakloop.u2demo.uidevice.FingerTest: Click(300,1000)
11-08 20:01:48.511 I/com.breakloop.u2demo.uidevice.FingerTest: Click = true
执行效果如下图:
从效果看,与之前采用waitForIdle的效果相同。但从日志里,可以发现,waitForWindowUpdate返回了False。原因在于,packageName与当前运行的App的packageName不相等。这一点可以从方法的源码中得到结论。
那么,如果packageName为null呢?官方文档中给出了说明,即,任何APP的window content update event都会结束等待。
我们将packageName改为null,看一下效果。
运行结果如下:
11-09 23:23:36.709 I/TestRunner: started: FunctionKeyTest4(com.breakloop.u2demo.uidevice.FingerTest)
11-09 23:23:36.711 I/MonitoringInstrumentation: Activities that are still in CREATED to STOPPED: 0
11-09 23:23:36.712 I/com.breakloop.u2demo.uidevice.FingerTest: Start Test
11-09 23:23:37.214 I/com.breakloop.u2demo.uidevice.FingerTest: left = 200 Right = 880
11-09 23:23:37.215 I/com.breakloop.u2demo.uidevice.FingerTest: from (880,906) to (200,906)
11-09 23:23:38.046 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Right to Left) = true
11-09 23:23:38.071 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = true
11-09 23:23:38.071 I/com.breakloop.u2demo.uidevice.FingerTest: from (200,906) to (880,906)
11-09 23:23:38.908 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Left to Right) = true
11-09 23:23:38.981 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = true
11-09 23:23:38.981 I/com.breakloop.u2demo.uidevice.FingerTest: Click(300,1000)
11-09 23:23:39.093 I/com.breakloop.u2demo.uidevice.FingerTest: Click = true
11-09 23:23:39.111 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = true
11-09 23:23:39.112 I/TestRunner: finished: FunctionKeyTest4(com.breakloop.u2demo.uidevice.FingerTest)
从日志里,可以发现,方法返回了true。
从效果上看,第一个滑动动作并没有完成,便开始第二个滑动动作了。因此,waitForWindowUpdate不会像waitForIdle一样,即使出现Idle也等待动作完成,而是只要出现WindowContentUpdate事件便停止等待。
那么,如果出现超时,方法是否会抛出异常呢?我们缩短Timeout的时间,为10毫秒。
效果如下:
执行结果如下:
11-09 23:46:46.690 I/TestRunner: started: FunctionKeyTest4(com.breakloop.u2demo.uidevice.FingerTest)
11-09 23:46:46.693 I/MonitoringInstrumentation: Activities that are still in CREATED to STOPPED: 0
11-09 23:46:46.693 I/com.breakloop.u2demo.uidevice.FingerTest: Start Test
11-09 23:46:47.194 I/com.breakloop.u2demo.uidevice.FingerTest: left = 200 Right = 880
11-09 23:46:47.195 I/com.breakloop.u2demo.uidevice.FingerTest: from (880,906) to (200,906)
11-09 23:46:48.014 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Right to Left) = true
11-09 23:46:48.025 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = false
11-09 23:46:48.025 I/com.breakloop.u2demo.uidevice.FingerTest: from (200,906) to (880,906)
11-09 23:46:48.840 I/com.breakloop.u2demo.uidevice.FingerTest: Swipe result (Left to Right) = true
11-09 23:46:48.851 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = false
11-09 23:46:48.851 I/com.breakloop.u2demo.uidevice.FingerTest: Click(300,1000)
11-09 23:46:48.963 I/com.breakloop.u2demo.uidevice.FingerTest: Click = true
11-09 23:46:48.974 I/com.breakloop.u2demo.uidevice.FingerTest: wait For Window Update, result = false
11-09 23:46:48.975 I/TestRunner: finished: FunctionKeyTest4(com.breakloop.u2demo.uidevice.FingerTest)
从执行效果看,第一个滑动未完成,最后点击操作未完成。点击之所以未完成,是因为测试案例执行结束。
从日志可看,waitForWindowUpdate在超时的情况下,并未抛出异常,而是返回false。但不论返回true或false,都立即执行后面的动作。
最后,再来解决一个核心问题:什么是windowUpdate?
查看方法的源码,可以发现,方法是对AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED事件的监听。
而对AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED的官方解释是:
represents the event of change in the content of a window. This change can be adding/removing view, changing a view size, etc
即view的添加,移除或大小的改变等。
那么TextView中内容的变化,是否会引发该事件呢?
答案是不会。内容变化应属于控件的状态变化。此前,我们在博文UIAutomator2.0详解(UIDevice篇—-触屏操作2)的实例中,使用过该方法,在输入数据后,可以从执行结果中看到,方法返回值为false,即在未超时的情况下,未发现AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED事件。
对于AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED的官方解释可参照:
https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityEvent.html