EventBus源码解析(二)

这一篇文章是基于上一篇文章的内容之上的的,在阅读这一篇文章之前请先阅读我的之前那篇文章EventBus源码解析(一)这里写链接内容
那么我们就马上进入主题吧,上篇文章分析到boolean sticky这个参数和registerSticky(Object subscriber)这个方法,这个方法与之前我们注册的方法是不是很像啊?

  public void register(Object subscriber) {
        this.register(subscriber, false, 0);
    }
   public void registerSticky(Object subscriber) {
        this.register(subscriber, true, 0);
    }

可以看出他们之间的区别了吗?在register()方法中,sticky被赋值为false,而registerSticky()方法将sticky被赋值为true。
后面的步骤跟上一篇文章中已经给大家分析的很清楚了,只有一个地方用到了sticky,让我们来看看是如何使用的吧:

 if(sticky) {
            Map var11 = this.stickyEvents;
            Object stickyEvent;
            synchronized(this.stickyEvents) {
                stickyEvent = this.stickyEvents.get(eventType);
            }

            if(stickyEvent != null) {
                this.postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
            }
        }

显然只有当sticky被赋值为true的时候才会进入这个if判断语句,stickyEvents是一个map集合,如果stickyEvents是空的,那么这段代码看上去好像没有什么意义,那么我们来看看stickyEvents这个map集合是什么时候往里面添加数据的。

  public void postSticky(Object event) {
        Map var2 = this.stickyEvents;
        synchronized(this.stickyEvents) {
            this.stickyEvents.put(event.getClass(), event);
        }

        this.post(event);
    }

原来是在postSticky(Object event)这个方法里添加的,原来registerSticky(Object subscriber)和postSticky(Object event)是一对啊!
等一下,为什么感觉有点奇怪呢,感觉是先发布,后注册!postSticky()这个方法好像在registerSticky()这个方法之前调用,因为只有你得先将数据添加到stickyEvents集合当中,然后才能从stickyEvents集合中获取到数据。

来分析一下吧,如果先发布postSticky(Object event),会将传入对象的Class作为Key,传入的对象作为值存入stickyEvents集合中,然后调用post(event),之前我们分析过了,post(event)主要是找到subscriptionsByEventType这个集合去取值,然后通过反射去调用相应的方法,但是这里我们都还没有注册,所以subscriptionsByEventType这个集合肯定是没有数据的,因此按理说是不会调用方法的,but但是还记得当我们注册的时候使用的是registerSticky()这个方法时不是有这段代码吗stickyEvent = this.stickyEvents.get(eventType); 这个时候stickyEvents集合里面是有数据的啊,那么stickyEvent 就不为null了,在往下看:

 if(stickyEvent != null) {
                this.postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
            }

进入到这个if()判断语句当中,会调用postToSubscription这个方法,

    private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
        switch(EventBus.SyntheticClass_1.$SwitchMap$de$greenrobot$event$ThreadMode[subscription.subscriberMethod.threadMode.ordinal()]) {
        case 1:
            this.invokeSubscriber(subscription, event);
            break;
        case 2:
            if(isMainThread) {
                this.invokeSubscriber(subscription, event);
            } else {
                this.mainThreadPoster.enqueue(subscription, event);
            }
            break;
        case 3:
            if(isMainThread) {
                this.backgroundPoster.enqueue(subscription, event);
            } else {
                this.invokeSubscriber(subscription, event);
            }
            break;
        case 4:
            this.asyncPoster.enqueue(subscription, event);
            break;
        default:
            throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }

    }

我想问这个方法你熟不熟?很熟了吧,不就是找到了对应的subscription对象通过反射调用对应的方法吗?现在你知道这个Boolean sticky是干什么用的了吧,它可以让我们倒着使用EventBus,这么说好像不太通俗,就是你可以先发布事件,我稍后注册依然可以找到你并调用对应的方法来实现通信的功能,但是跟先注册后发布还是有区别的,这次我并不是从subscriptionsByEventType拿到的数据,而是从stickyEvents这个集合中拿到的数据哦!
这篇文章就分析到这里了,通过这两篇文章来总结一下EventBus:
它既可以先注册,然后再发布对象,也可以先发布对象,后注册调用相应的方法。
还有就是在项目中使用EventBus时我曾经踩过一个坑,当时线程我们封装起来了,结果post(Object event)是在子线程中调用的,而我却在onEventMainThread()中写代码…….. 这里一定要注意,在那个线程发布事件,就要在对应的方法中写代码,好了,通过这两篇文章,EventBus源码的已经分析完了,希望这两篇文章能帮到大家的同时让自己的思路也更加清晰。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值