[UiAutomator] UiSelector中使用instance與index方法定位控件的區別


在使用UiAutomator寫測試用例時,最常用到的就是控件查找操作。

在UiSelector中,有兩個定位控件的方法,一個是instance,一個是index。那么這兩個方法有什么區別呢?

首先,我們看一下官方api說明:

instance(int instance):
Set the search criteria to match the widget by its instance number. The instance value must be 0 or greater, where the first instance is 0. For example, to simulate a user click on the third image that is enabled in a UI screen, you could specify a a search criteria where the instance is 2, the className(String) matches the image widget class, and enabled(boolean) is true. The code would look like this: new UiSelector().className("android.widget.ImageView") .enabled(true).instance(2);

index(int index):
Set the search criteria to match the widget by its node index in the layout hierarchy. The index value must be 0 or greater. Using the index can be unreliable and should only be used as a last resort for matching. Instead, consider using the instance(int) method.

也就是說instance方法會將界面上所有相同類型的控件按順序取出來,放到一個集合里(暫且這么理解吧,不知道放哪里了,囧),然后按照控件在集合的角標把想要的控件取出來;而index則是通過該控件所在層級的節點角標將對應的控件取出來。

那么這兩個方法到底是怎么使用的呢?看下面的例子:

首先我們通過xml定義一個布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="textview1"
        android:textSize="22sp" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button1" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="textview2"
        android:textSize="22sp" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button2" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="textview3"
        android:textSize="22sp" />

</LinearLayout>

使用UiAutomatorViewer截出來的圖是這樣的:

image

按照說明,使用index方法獲取TextView控件是這樣的:

UiObject obj = new UiObject(new UiSelector().className("android.widget.TextView").index(0)); // textview1
UiObject obj = new UiObject(new UiSelector().className("android.widget.TextView").index(2));  // textview2
UiObject obj = new UiObject(new UiSelector().className("android.widget.TextView").index(4));  // textview3

哎,等等,尼瑪!為啥我第一個方法取到的UiObject是“TestUI”?原來在我們的TitleBar上也有一個TextView控件,而它的節點角標也是0(見下圖)。這是不是太坑爹了?先不要埋怨,人家api文檔都說的很清楚了,這是一個不靠譜(unreliable)的方法,其他方法都不好使了才建議去嘗試此方法。

image

下面把使用instance方法獲取TextView控件的方法寫出來:

UiObject obj = new UiObject(new UiSelector().className("android.widget.TextView").instance(0)); // TestUI
UiObject obj = new UiObject(new UiSelector().className("android.widget.TextView").instance(1)); // textview1
UiObject obj = new UiObject(new UiSelector().className("android.widget.TextView").instance(2));  // textview2
UiObject obj = new UiObject(new UiSelector().className("android.widget.TextView").instance(3));  // textview3

怎么樣,使用instance方法就靠譜多了吧。

本次分享到此結束,歡迎大家與我一起交流。

============================2014-12-25 分割線===================

今天上網看博客,發現index方法還有一種用法,就是在UiObject.getChild()方法里使用。還是以上面的UI為例。

如果我們想要獲取textview1對應的TextView控件,首先找到它的父控件LinearLayout,而LinearLayout又是FrameLayout的子控件(如下圖)。

所以,獲取textview1的代碼大概是這樣:

UiObject viewObj = new UiObject(new UiSelector().className("android.view.View")); // 獲取View控件
UiObject flObj = viewObj.getChild(new UiSelector().index(1)); // 獲取FrameLayout控件
UiObject llObj = flObj.getChild(new UiSelector().index(0)); // 獲取LinearLayout控件
UiObject tv1Obj = llObj.getChild(new UiSelector().index(0)); // 獲取textview1對應的TextView控件

 

怎么樣?還是instance好用吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM