美文网首页
EventBus 源码解析 加备注

EventBus 源码解析 加备注

作者: cao苗子 | 来源:发表于2019-11-06 11:04 被阅读0次

    源码备注地址:
    https://github.com/panshimu/EventBus

    1.注册:EventBus.getDefault().register(this);

    第一步:查找所有订阅者中标有Subscribe注解的方法,然后获取该方法中的所有属性封装到SubscriberMethod中,放到List集合 subscriberMethods 中。

    第二步:遍历subscriberMethods集合,根据订阅者和SubscriberMethod构建一个Subscription,并且根据方法参数类型够着一个List集合CopyOnWriteArrayList存储
    Subscription,并以方法参数class类型为key,CopyOnWriteArrayList为value存贮到Map集合subscriptionsByEventType中。

    第三步:根据订阅者创建一个List集合subscribedEvents用于存储该订阅者下所有类型参数class的集合,并且把这个订阅者和这个集合存储到map集合typesBySubscriber中,key是订阅者,value是subscribedEvents集合。

    register()的任务到这里就完毕了。

    2.发送: EventBus.getDefault().post("miaozi");

    post就相对比较简单了。
    首先是根据发送的数据类型 获取对应的class对象,根据class对象在subscriptionsByEventType中查找,得到CopyOnWriteArrayList中存储的Subscription,然后遍历Subscription订阅者得到具体的订阅者就可以得到绑定的SubscriberMethod,里面有很多的参数,得到其中的method方法就可以直接invoke了。
    subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
    这样就能成功的发送消息了。
    里面还有一些讲究,比如在子线程发送等等,就是用了handler和线程池的模式来处理的。大家可以自己阅读源码,应该不难看懂。

    3.注销:EventBus.getDefault().unregister(this);

    注销及更简单了,根据订阅者在typesBySubscriber获取所有方法参数Class,然后遍历Class,再根据class在subscriptionsByEventType中查找所有的Subscription,然后一个一个删除就好了。代码如下,很简单:

    public synchronized void unregister(Object subscriber) {
            //根据订阅者class删除
            List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
            if (subscribedTypes != null) {
                for (Class<?> eventType : subscribedTypes) {
                    unsubscribeByEventType(subscriber, eventType);
                }
                typesBySubscriber.remove(subscriber);
            } else {
                logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
            }
        }
    
    
    private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
            //根据订阅者 中的方法参数class
            List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
            if (subscriptions != null) {
                int size = subscriptions.size();
                for (int i = 0; i < size; i++) {
                    Subscription subscription = subscriptions.get(i);
                    if (subscription.subscriber == subscriber) {
                        subscription.active = false;
                        subscriptions.remove(i);
                        i--;
                        size--;
                    }
                }
            }
        }
    

    相信大家一看就懂。

    到这里就结束了。具体的源码备注在开头的github连接上。

    ok

    总结:
    注册:
    1.遍历所有注册类带有Subscribe注解方法,封装成SubscriberMethod存贮到List<SubscriberMethod>集合中。
    2.遍历List<SubscriberMethod>,创建Subscription对象存贮 注册类 和 subscriberMethod。根据方法参数类型,创建Map<方法参数类型,CopyOnwriteArrayList<Subscription>>,存贮Subscription。然后再次创建一个Map<注册类,方法参数集合>,这个主要是为了方便移除。

    相关文章

      网友评论

          本文标题:EventBus 源码解析 加备注

          本文链接:https://www.haomeiwen.com/subject/mvxubctx.html