观察者模式在EventBus中的应用

git地址:https://github.com/greenrobot/EventBus.git

EventBus是Android的事件发布以及订阅框架,通过解耦发布者和订阅者简化Android事件传递,即消息传递。事件传递可以用于四大组件间通讯以及异步线程和主线程间通讯等。

EventBus代码简洁易于使用,可用于应用内的消息事件传递,耦合低,方便快捷。

基础部分代码为:

public class EventBusMain extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);


        EventBus.getDefault().register(this);

    }

  - 订阅的事件 onEvent1
    @Subscribe
    public void onEvent1(RemindBean bean){

    }
- 订阅的事件 onEvent2
    @Subscribe
    public void onEvent2(UserInfo bean){

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

当需要发送消息传递的时候:

EventBus.getDefault().post(new RemindBean())

即发布者通过post()事件到EventBus,然后由EventBus将事件发送给各订阅者。

之前的开发人员要想实现不同activity之间的数据传递,需要开发大量接口,而EventBus可以方便快捷地解决这个问题。

发布事件中的参数是Event的实例,而订阅函数中的参数也是Event的实例,可以推断EventBus是通过post函数传进去的类的实例来确定调用哪个订阅函数的,是哪个就调用哪个,如果有多个订阅函数,那么这些函数都会被调用。

通过发布不同的事件类的实例,EventBus根据类的实例分别调用了不同的订阅函数来处理事件。

首先通过register()通过Subscriber确定订阅者以及通过Event确定订阅内容:

 EventBus.getDefault().register(this);

 /** Convenience singleton for apps using a process-wide EventBus instance. */
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }
public void register(Object subscriber) {
        //订阅者(subscriber)类的字节码
        Class<?> subscriberClass = subscriber.getClass();

        //通过这个类的字节码,拿到所有的订阅的 event,存放在List中
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);

        synchronized (this) {
          //循环遍历所有的订阅的方法,完成subscriber 和 subscriberMethod 的关联
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

在Subscribe中确定消息的类型(是否为粘滞消息)以及优先级,用于消息的发送。

public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;

    /**
     * If true, delivers the most recent sticky event (posted with
     * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
     */
    boolean sticky() default false;

    /** Subscriber priority to influence the order of event delivery.
     * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
     * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
     * delivery among subscribers with different {@link ThreadMode}s! */
    int priority() default 0;
}

// Must be called in synchronized block
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
- 1. 订阅方法的eventType的字节码
Class<?> eventType = subscriberMethod.eventType;

 
 

//订阅者和订阅方法封装成一个Subscription 对象
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);

 
 

//subscriptionsByEventType 第一次也是null ,根据eventType
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);

 
 

//第一次为null
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();

 
 

//key 为 eventType, value 是subscriptions对象
subscriptionsByEventType.put(eventType, subscriptions);
} else {
//抛出异常
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}

 
 

//获取所有添加的subscriptions
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
// 会判断每个订阅方法的优先级,添加到这个 subscriptions中,按照优先级
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}

//获取订阅的方法集合
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
//为空添加到 typesBySubscriber
typesBySubscriber.put(subscriber, subscribedEvents);
}
//订阅事件添加到subscribedEvents集合中去
subscribedEvents.add(eventType);

 
 

//判断是否是粘性事件的关联
if (subscriberMethod.sticky) {
if (eventInheritance) {
// Existing sticky events of all subclasses of eventType have to be considered.
// Note: Iterating over all events may be inefficient with lots of sticky events,
// thus data structure should be changed to allow a more efficient lookup
// (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}

 

通过调用Android的handler监听传递的事件,即发布者发布、订阅者订阅模式,这里用到了观察者模式。

protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
        super(looper);
        this.eventBus = eventBus;
//调用Android的handler监听
this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage; queue = new PendingPostQueue(); } public void enqueue(Subscription subscription, Object event) { PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event); synchronized (this) { queue.enqueue(pendingPost); if (!handlerActive) { handlerActive = true; if (!sendMessage(obtainMessage())) { throw new EventBusException("Could not send handler message"); } } } } @Override public void handleMessage(Message msg) { boolean rescheduled = false;
//抛出异常
try { long started = SystemClock.uptimeMillis(); while (true) { PendingPost pendingPost = queue.poll(); if (pendingPost == null) { synchronized (this) { // Check again, this time in synchronized pendingPost = queue.poll(); if (pendingPost == null) { handlerActive = false; return; } } } eventBus.invokeSubscriber(pendingPost); long timeInMethod = SystemClock.uptimeMillis() - started; if (timeInMethod >= maxMillisInsideHandleMessage) { if (!sendMessage(obtainMessage())) { throw new EventBusException("Could not send handler message"); } rescheduled = true; return; } } } finally { handlerActive = rescheduled; } }

通过findSubscriberMethod()根据subscriberClass找到订阅的method:

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
       //先从缓存中取
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);

        //第一次 null
        if (subscriberMethods != null) {
            return subscriberMethods;
        }
   if (ignoreGeneratedIndex) { subscriberMethods = findUsingReflection(subscriberClass); } 

  else { subscriberMethods = findUsingInfo(subscriberClass); }

  if (subscriberMethods.isEmpty()) {
    
throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation"); }

  else { //找到之后添加到缓存中,key是 subscriber ;value 是:methods
      METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods; } }

获取消息状态,确定传给正确的订阅者:

private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
        FindState findState = prepareFindState();

        将订阅者的subscriberClass 存储起来,保存在一个FindState 类中的subscriberClass 同时赋值给clazz变量中
//      void initForSubscriber(Class<?> subscriberClass) {
 //      this.subscriberClass = clazz = subscriberClass;
//}
        findState.initForSubscriber(subscriberClass);

        while (findState.clazz != null) {进入循环中
          //获取subscriberInfo 信息,返回null
            findState.subscriberInfo = getSubscriberInfo(findState);
            if (findState.subscriberInfo != null) {
                SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
                for (SubscriberMethod subscriberMethod : array) {
                    if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
                        findState.subscriberMethods.add(subscriberMethod);
                    }
                }
            } else {
                 //所有信息保存到findState中
                findUsingReflectionInSingleClass(findState);
            }
            //查找父类中的方法
            findState.moveToSuperclass();
        }
        return getMethodsAndRelease(findState);
    }
private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
        //取出里面的subscriberMethods
        List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);
        findState.recycle();
        synchronized (FIND_STATE_POOL) {
            for (int i = 0; i < POOL_SIZE; i++) {
                if (FIND_STATE_POOL[i] == null) {
                    FIND_STATE_POOL[i] = findState;
                    break;
                }
            }
        }
      //返回集合
        return subscriberMethods;
    }

猜你喜欢

转载自www.cnblogs.com/susana-ustc/p/9839420.html