(本文基于:'androidx.test.uiautomator:uiautomator:2.2.0')
Until类介绍
Until类位于androidx.test.uiautomator包中,该类中定义了很多静态工厂方法,这些静态工厂方法的一个共同特点是都会返回表示等待条件的对象,如EventCondition、UiObject2Condition、SearchCondition,这些对象集中在UiDevice、UiObject2的方法中使用
Until的静态工厂方法初步介绍
Until类中的静态工厂方法,按照返回值对象的不同类型分类,返回的类型有:
1、UiObject2Condition对象
这个对象表示与UiObject2对象属性状态相关联的条件对象,比如与UiObject2表示的控件点击状态有关
2、SearchCondition对象
这个对象表示与Searchable接口相关联的条件对象(UiDevice、UiObject2均实现了Searchable接口),比如最直接的体现就是查找控件了
3、EventCondition对象
这个对象表示与Event事件相关联的条件对象,比如窗口更新事件
UiObject2Condition、SearchCondition、EventCondition集中介绍
这三个类产生的对象都表示等待条件,这三个类全部继承Condition类,Condition类作为他们的基类,位于androidx.test.uiautomator包中,它是一个抽象泛型类,只规范了一个待实现的功能,它就是抽象泛型方法apply()方法。
Until的静态工厂方法源码分析
在Until类中的静态工厂方法全部采用匿名内部类的写法,为了缩短本篇文章的长度,我将选择每个返回类型的具有代表意义的一个方法进行源码分析,本篇文章将分析以下3个方法:
1、返回UiObject2Condition对象的clickable方法
2、返回SearchCondition的findObject方法
3、返回EventCondition的newWindow方法!
Until的静态方法clickable()源码分析
public static UiObject2Condition<Boolean> clickable(final boolean isClickable) {
return new UiObject2Condition<Boolean>() {
@Override
Boolean apply(UiObject2 object) {
return object.isClickable() == isClickable;
}
};
}
总览
匿名内部类写法,返回的UiObject2Condition对象表示依赖于UiObject2可点击状态的一个条件,UiObject2Condition对象唯一使用的位置是在UiObject2中的wait方法中!
方法体
1、方法内部采用匿名内部类形式返回UiObject2Condition对象
2、创建该匿名对象的同时,重写了apply方法
3、而这个apply方法是在UiObject2的wait()方法中回调的,回调的时候会传入一个UiObject2对象,在apply()方法的内部,判断传入的UiObject2对象的点击状态是否与预期的点击状态一致,如果点击状态是相同的,apply方法就会返回true、点击状态不同则会返回一个false!
Until的静态方法findObject()源码分析
public static SearchCondition<UiObject2> findObject(final BySelector selector) {
return new SearchCondition<UiObject2>() {
@Override
UiObject2 apply(Searchable container) {
return container.findObject(selector);
}
};
}
总览
返回一个依赖与UiDevice或者UiObject查找到控件的SearchCondition条件对象,当找到一个与BySelector对象(选择器对象)匹配的控件元素时,该条件才能得到满足,这个SearchCondition对象的使用位置有两处,一个是在UiDevice的wait方法,另一个则是在UiObject2定义的wait方法中使用!
方法体
1、匿名的SearchCondition对象中,重写了apply()方法
2、apply方法会在UiDevice或者UiObject2的wait方法中回调,而apply方法的container参数,此时根据使用者的不同,实际传入的对象也是不同的
3、当UiDevice使用此方法时,container实际指向的是UiDevice对象
4、当UiObject2对象使用时此方法时,container实际指向的是UiObject2对象
5、通过UiDevice或者UiObject2的findObject()方法可以得到一个UiObject2对象或者一个null,最后apply方法的返回值对象将作为UiDevice的wait()方法或者UiObject2的wait()方法的返回值!
Until的EventCondition()方法源码分析
public static EventCondition<Boolean> newWindow() {
return new EventCondition<Boolean>() {
private int mMask = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED |
AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
@Override
Boolean apply(AccessibilityEvent event) {
mMask &= ~event.getEventType();
return mMask == 0;
}
@Override
Boolean getResult() {
return mMask == 0;
}
};
}
返回一个依赖于新窗口出现的条件对象,返回值是EventCondition对象
使用者
分别是GestureController#performGestureAndWait方法,UiDevice#performActionAndWait方法,UiObject2#clickAndWait方法
总结
1、Until类提供如此众多的静态工厂方法,便于我们获取一个等待条件对象
2、无论使用UiDevice、还是UiObject2的等待功能,必须使用Until类获得指定的等待条件