public abstract class AbsHTTPRequest { private final WeakHashMap<OnChangedListener, Boolean> mListeners = new WeakHashMap<OnChangedListener, Boolean>(); public interface OnChangedListener { void onDataChanged(); } /*HTTP's response*/ public abstract void onResponse(); public final void addListener(OnChangedListener listener) { mListeners.put(listener, true); } public final void removeListener(OnChangedListener listener) { mListeners.remove(listener); } protected final void notifyDataChanged() { Set<OnChangedListener> keys = mListeners.keySet(); if(keys != null) { Iterator<OnChangedListener> iterator = keys.iterator(); while(iterator.hasNext()) { iterator.next().onDataChanged(); } } } }详细的主题角色( 被观察者),实现方式例如以下:
public class LoginRequest extends AbsHTTPRequest implements OnChangedListener{ public void onResponse(){ addListener(this); notifyDataChanged(); } @Override public void onDataChanged() { // TODO Auto-generated method stub System.out.println("LoginRequest"); } }使用观察者模式有一个弊病就是部件之间的耦合度太高,全部的主题角色都须要实现同一个interface。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同一时候监听某一个主题对象。
假设主题角色被注冊的observer越多。那么须要实现的interface也就越多,接口方法数量也就越多。
怎样来进行解耦,让代码逻辑更清晰。可读性更强。是一个问题。
在Android中也有一个类似功能的开源库EventBus。能够非常方便的帮助我们实现观察者模式,而且让各个组件之间的耦合性更低。
首先知道怎样使用,然后再深究源代码,才干循序渐进,吃透当中的设计理念。便于日后的代码调试和模块重构。关于demo,网上有非常多,能够自己去查收。
SubscribMethod.java final class SubscriberMethod { final Method method; /*Method类型的method成员表示这个onEvent,即事件处理函数。Subscription.java同一时候也包括订阅源*/ final ThreadMode threadMode; final Class<?> eventType; /*事件的对象,用户自己定义Object*/ ... ... ... ... ... ... ... ... ... ... ... ... }
final class Subscription { final Object subscriber; /*订阅源Subscriber,即调用register注冊的对象*/ final SubscriberMethod subscriberMethod; /**/ final int priority; ... ... ... ... ... ... ... ... ... ... ... ... }
/*EventType -> List<Subscription>,事件到订阅对象之间的映射*/ private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType; /* Subscriber -> List<EventType>,订阅对象到它订阅的的全部事件的映射关系*/ private final Map<Object, List<Class<?>>> typesBySubscriber;注冊流程:在调用register函数时,EventBus类有多个重载的register函数,可是作者更倾向于使用register(this);含有 多个參数的register函数中,明白标注了@deprecated,原创作者不建议使用。
从代码:
public void register(Object subscriber) { register(subscriber, DEFAULT_METHOD_NAME, false, 0); }能够观察到,全部重载的register函数。都调用到了
private synchronized void register(Object subscriber, String methodName, boolean sticky, int priority) { List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriber.getClass(),methodName); for (SubscriberMethod subscriberMethod : subscriberMethods) { subscribe(subscriber, subscriberMethod, sticky, priority); } }当中注冊函数register。默认參数DEFAULT_METHOD_NAME为函数名称"onEvent",在java放射机制中,全部的事件处理函数名称 统一为“onEvent”,只參数不一致。onEvent的參数为用户自己定义的对象。
这也是为啥,我们的onEvent函数,要定义为public方法的原因哦。
每个订阅者,相应一个List<SubscriberMethod>。有多少onEvent函数,返回的List,就有多少个item。
即查找订阅源内的事件处理方法,同一时候还会查到它的父类中的事件处理方法。返回list,交给private void subscribe(Object subscriber, SubscriberMethod subscriberMethod, boolean sticky, int priority)进行处理。
即一个事件,能够被多个订阅者关注。
Subscriber与Event之间,也是一对多的关系。
即一个订阅者,能够订阅多个事件。
与Observer不同的是。使用EventBus。不同的被观察者,不需统一实现Observer中的interface方法。在上层代码中,也不须要逐一进行notify机制。通过Map进行订阅源与事件函数的相应关系,进行解耦,为其核心之处。
发送流程:
EventBus.getDefault().post(new EventType());參数为用户自己定义的对象。最为简单的处理方式,实现事件发送。
当事件发送出去后,全部的订阅者。是怎样调用其事件方法的呢?这个就须要遍历上文提到的subscriptionsByEventType的Map了。Post发送事件,入口为post函数:public void post(Object event),在postSingleEvent函数中个,有一个重要的处理函数:
/** Finds all Class objects including super classes and interfaces. */ private List<Class<?>> findEventTypes(Class<?其作用。就是把这个事件类的对象、实现的接口及父类的类对象存到一个List中返回。依据list中的eventTypes,遍历subscriptionsByEventType,获取订阅源对象。进行逐一的调用事件函数。> eventClass) { synchronized (eventTypesCache) { List<Class<?>> eventTypes = eventTypesCache.get(eventClass); if (eventTypes == null) { eventTypes = new ArrayList<Class<?
>>(); Class<?> clazz = eventClass; while (clazz != null) { eventTypes.add(clazz); addInterfaces(eventTypes, clazz.getInterfaces()); clazz = clazz.getSuperclass(); } eventTypesCache.put(eventClass, eventTypes); } return eventTypes; } }
原文:http://www.cnblogs.com/yxwkf/p/5141038.html