1. 程式人生 > >UIAutomator2.0詳解(UIDevice篇----waitForWindowUpdate)

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事件。