“在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,一来它的对象都会收到通知”
场景:
某一个对象(或者数据)更新了,其他的一些类也要跟着变化,比如,在Android中,某个数据发生了改变,多处的UI要同时随之变化。
解决思路:
1.建立一个被监听的内容类(Observable),这个类实现一个接口,里面有三个主要方法,register,unregister,notifyObserver。
notifyObserver方法当监听对象发生变化时调用,把这个消息告诉所有的监听者(Observer)
register方法提供给Observer 这注册使用,Observer调用此方法后,就能收到notifyObserver传来的消息
unregister用来取消注册
2.所有的监听者实现Observer接口。该接口主要有一个update方法,当监听对象发生变化时,这个方法会被调用
public class Publisher implement Observable {
//构建一个列表,里面放着所有订阅了这个监听对象的监听者的引用
private ArrayList<Observer> observerList;
public Publisher() {
observerList = new ArrayList<Observer>;
}
@Override
public void register(Observer ob) {
observerList.add(ob); //注册其实就是把这个监听者的引用加入到上面那个队列里
}
@Override
public void unregister(Observer ob) {
int index = observerList.indexOf(o);
if (index >= 0) {
observerList.remove(index);
}
}
//其实就是拿出上面那个list里的所有监听者,然后依次调用他们的update方法
@Override
public void notifyObserver() {
for(int i = 0; i < observerList.size(); i++) {
observerList.get(i).update;
}
}
}
public class Subscriber() implement Observer {
private Publisher publisher;
//初始化的时候需要告诉监听者具体要监听谁
public Subscriber(Publisher publisher) {
this.publisher = publisher;
publisher.register(this);
}
@Override
public void update() {
//收到消息后的处理
}
}
在Android中的应用:Otto EventBus
Otto 是Android系统的一个Event Bus模式类库。用来简化应用组件间的通信Read more: http://blog.chengyunfeng.com/?p=450
Otto的用法:在组件的相关生命周期中通过Bus类的register 函数来注册,然后Bus类会扫描改类中带有@Produce和 @Subscribe 注解的函数。
@Subscribe 注解告诉Bus该函数订阅了一个事件,该事件的类型为该函数的参数类型;而@Produce注解告诉Bus该函数是一个事件产生者,产生的事件类型为该函数的返回值。
post方法用来发布一个事件
register方法:
1. 首先把这个页面的所有pushisher和Subscribers 全部遍历出来,我们重点看Subscriber, 遍历Subscribers的核心代码如下:
Map<Class<?>, Set<EventHandler>> foundHandlersMap = handlerFinder.findAllSubscribers(object); //取出这个object里所有带subscribe装饰器的函数
for (Class<?> type : foundHandlersMap.keySet()) { //遍历这些函数
Set<EventHandler> handlers = handlersByType.get(type); //看看这些函数有没有已经被注册过
if (handlers == null) {
//concurrent put if absent
Set<EventHandler> handlersCreation = new CopyOnWriteArraySet<EventHandler>();
handlers = handlersByType.putIfAbsent(type, handlersCreation);
if (handlers == null) {
handlers = handlersCreation;
}
}
final Set<EventHandler> foundHandlers = foundHandlersMap.get(type);
handlers.addAll(foundHandlers); //如果没有,就把这些函数放入handlersByType里,handlersByType就相当于标准实现里的observerList
}
2.当一个新的消费发出时,会调用post方法:
public void post(Object event) {
if (event == null) {
throw new NullPointerException("Event to post must not be null.");
}
enforcer.enforce(this);
Set<Class<?>> dispatchTypes = flattenHierarchy(event.getClass());
boolean dispatched = false;
for (Class<?> eventType : dispatchTypes) {
Set<EventHandler> wrappers = getHandlersForEventType(eventType); //从handlersByType里拿出相应的方法,这个是根据传进来的class类型来过滤的
if (wrappers != null && !wrappers.isEmpty()) {
dispatched = true;
for (EventHandler wrapper : wrappers) {
enqueueEvent(event, wrapper);
}
}
}
if (!dispatched && !(event instanceof DeadEvent)) {
post(new DeadEvent(this, event));
}
dispatchQueuedEvents();
}