“在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,一来它的对象都会收到通知”

场景:
某一个对象(或者数据)更新了,其他的一些类也要跟着变化,比如,在Android中,某个数据发生了改变,多处的UI要同时随之变化。

解决思路:
1.建立一个被监听的内容类(Observable),这个类实现一个接口,里面有三个主要方法,register,unregister,notifyObserver。

notifyObserver方法当监听对象发生变化时调用,把这个消息告诉所有的监听者(Observer)
register方法提供给Observer 这注册使用,Observer调用此方法后,就能收到notifyObserver传来的消息
unregister用来取消注册

2.所有的监听者实现Observer接口。该接口主要有一个update方法,当监听对象发生变化时,这个方法会被调用

public class Publisher implement Observable {          //构建一个列表,里面放着所有订阅了这个监听对象的监听者的引用     private ArrayList observerList;          public Publisher() {          observerList = new ArrayList;     }     @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, Set> foundHandlersMap = handlerFinder.findAllSubscribers(object);  //取出这个object里所有带subscribe装饰器的函数    for (Class<?> type : foundHandlersMap.keySet()) {   //遍历这些函数      Set handlers = handlersByType.get(type);    //看看这些函数有没有已经被注册过      if (handlers == null) {        //concurrent put if absent        Set handlersCreation = new CopyOnWriteArraySet();        handlers = handlersByType.putIfAbsent(type, handlersCreation);        if (handlers == null) {            handlers = handlersCreation;        }      }      final Set 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> dispatchTypes = flattenHierarchy(event.getClass());    boolean dispatched = false;    for (Class<?> eventType : dispatchTypes) {      Set 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();  }     

 

更多相关文章

  1. matix in Android
  2. android的CursorLoader用法小结
  3. Android开发之进程与线程
  4. 在Android(安卓)Studio 中加入jar 和.so 文件
  5. Android(安卓)模拟器解决公司网络内无法上网的另类解决方法
  6. Android(安卓)9.0 电源管理之省电模式
  7. Android(安卓)的 Sqlite基本操作
  8. 关于Android(安卓)HTML5 audio autoplay无效问题的解决方案
  9. Android(安卓)利用OnDraw实现自定义View

随机推荐

  1. android app 缓存 ---- android 文件缓存
  2. android学到啥时候就高级了啊
  3. 【Android增量升级系列_02】 浅谈Android
  4. Android(安卓)Canvas练习(1)画一张报表来
  5. android编程之在单线程模型中Message、Ha
  6. 19_利用android提供的HanziToPinyin工具
  7. android架构之美
  8. 两份安卓学习资料,我建议你看完
  9. 最近,又有人在谈论Android的前景了!深入解
  10. 最近Android挺火啊,都没有什么感想吗