(本文基于:'androidx.test.uiautomator:uiautomator:2.2.0')
在UI Automator测试框架中,我们每次创建的UiDevice对象表示一台Android设备(手机、平板、电视,运行着Android系统的都是Android设备),UiDevice提供了很多功能,比如与控件相关的功能、与操作屏幕的相关的功能,详细功能请查看UiDevice基本介绍那篇文章。在操作控件的相关方法中,有一套和UiWatcher相关的方法:注册UiWatcher的方法、取消注册UiWatcher的方法以及运行所有已注册的UiWatcher的方法,这3个方法构成了本篇文章介绍的《观察者模式》!
《观察者模式》在编写代码中的使用率非常高,说明这个设计模式能切实的解决实际问题,它的重要作用是解耦能力,将被观察者与观察者解耦。
《观察者模式》定义:对象之间的一对多依赖关系,每当一个对象改变状态,则所有依赖它的多个对象都会得到通知并被自动更新状态(属性)!此处的一对多,一是被观察者对象,多则是观察者对象!
《观察者模式》属于行为型模式,每个设计模式都有固定的定义,在实际开发中,一般会根据定义去灵活变化,可以称为不同的形式或者不同的变体比较合适,但总的思想是一致的!
《观察者模式》的别称:发布-订阅Subscribe模式、模型Model-视图View模式、源-收听者Listener模式、从属者模式………………这些别称说的是一回事!接下来学习UiDevice中对于《观察者模式》的如何实现的?
本篇文章展示UiDevice中的观察者模式代码,具体的代码细节不再多说!!
public class UiDevice implements Searchable {
………………省略很多代码……………
//用于保存注册的观察者
private final HashMap<String, UiWatcher> mWatchers = new HashMap<String, UiWatcher>();
//注册观察者
public void registerWatcher(String name, UiWatcher watcher) {
Tracer.trace(name, watcher);
if (mInWatcherContext) {
throw new IllegalStateException("Cannot register new watcher from within another");
}
mWatchers.put(name, watcher);
}
//取消注册观察者
public void removeWatcher(String name) {
Tracer.trace(name);
if (mInWatcherContext) {
throw new IllegalStateException("Cannot remove a watcher from within another");
}
mWatchers.remove(name);
}
//通知所有注册的观察者
public void runWatchers() {
Tracer.trace();
if (mInWatcherContext) {
return;
}
for (String watcherName : mWatchers.keySet()) {
UiWatcher watcher = mWatchers.get(watcherName);
if (watcher != null) {
try {
mInWatcherContext = true;
if (watcher.checkForCondition()) {
setWatcherTriggered(watcherName);
}
} catch (Exception e) {
Log.e(LOG_TAG, "Exceuting watcher: " + watcherName, e);
} finally {
mInWatcherContext = false;
}
}
}
}
}
UiDevice对象持有的一个容器类HashMap对象mWatchers专门用来存储注册的观察者-> UiWatcher对象
registerWatcher方法用于注册观察者- > UiWatcher对象
removeWatcher方法用于取消注册观察者- > UiWatcher对象
runWatchers方法用于通知所有注册的观察者-> UiWatcher对象
对应到《观察者模式》的定义中,此时的UiDevice对象是【被观察者】、每个UiWatcher对象则对象的是【观察者】。
当UiDevice的runWatchers()方法被回调时,UiDevice对象本身的状态并没有发生改变,也就是说UiDevice中实现的《观察者模式》与基本定义的《观察者模式》思路是相同的,但没有严格遵守所谓的标准定义。每当在当前Window中找不到控件时,UiDevice对象作为被观察者会通知所有注册的UiWatcher观察者对象执行,而这个“状态”并不是UiDevice对象持有的状态,而是抽象出来的一个状态,这个状态对应的是:在Window中是否找到控件,每当找不到控件,就相当于UiDevice的“状态”发生改变,因为过去的“状态”是可以找到控件!状态由“找到”过渡到"找不到",这就是一个状态的变化!!