UIAutomator2.0詳解(UIDevice篇----waitForWindowUpdate)
書接上文(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事件。