EventBus3.0源码浅析与理解

Posted 单灿灿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EventBus3.0源码浅析与理解相关的知识,希望对你有一定的参考价值。

1.简介

EventBus 是一个 android 事件发布/订阅框架。
传统的事件传递方式包括:Handler(消息处理机制,一般用于更新UI)、BroadCastReceiver(广播接收者)、Interface 回调。

EventBus优点:

  • Activity、Fragment、Service与线程之间的通讯是很常见的,EventBus正好可以屏蔽一些线程切换问题,简单地实现发布订阅功能。
  • 代码简洁,使用简单,并将事件发布和订阅充分解耦。

EventBus缺点:

  • 他的代码逻辑不是很清楚,在 Subscriber 注册的时候,Subscriber 中的方法会被遍历查找以 onEvent 开头的 public 方法,而Interface 回调则是查找实现者。
  • 而且若是EventBus传递较多类型的消息,那么消息类的数量必然是会爆炸性增长。
  • 调试的时候必须熟悉代码,不然不断点你是没办法找到Subscribe的方法的数据来源。

使用方法

注册订阅者

@Override
  public void onCreate() 
    //3.0版本的注册,2.x不再介绍
    EventBus.getDefault().register(this);

编写响应事件订阅方法

我们可以自定义自己的事件类,例如:

public class CreateFolderEvent 
  //一个创建文件夹的事件
    public File folder;
    public String parentPath;

    public CreateFolderEvent(File folder, String parentPath) 
        this.folder = folder;
        this.parentPath = parentPath;
    

注册之后,我们接着编写响应事件的方法,如下:

    //threadMode和sticky使用下文会讲
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onReceiveCreateFolderEvent(CreateFolderEvent event) 

      Log.e("Subscribe",event.parentPath);
    

发送自定义事件(自定义的 EventType)

通过EventBus的post()方法来发送事件,对应的接收方就会收到信息并通过Event来获取传递的对象.EventBus或者通过postSticky()来发送一个粘性事件.

粘性事件:何为黏性事件呢?简单讲,就是在发送事件之后再订阅该事件也能收到该事件,跟黏性广播类似。

举例场景:如我想发送一个事件给一个Activity,但是那个activity还没有创建。又想让activity创建时收到,可以用postSticky()。

示例如下:

   private void updateCreateFolderUI(String message) 
        File item = new File();
        mCurrentPath="/Sdcard/";
       EventBus().getDefault().post(new CreateFolderEvent(item, mCurrentPath));
       //或者是
       EventBus().getDefault().postSticky(new CreateFolderEvent(item, mCurrentPath));
    

解除EventBus注册

一般在onDestory()方法中取消订阅:防止内存溢出。

    @Override
    public void onDestroy() 
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    

EventBus 主要类的关系图.

从中我们也可以看出大部分类都与 EventBus 直接关联。上部分主要是订阅者相关信息,中间是 EventBus 类,下面是发布者发布事件后的调用。

使用方法介绍完了,下面让我们来对EventBus进行简单的源码分析

EventBus 源码解析

EventBus的订阅者、发布者、EventBus 关系图与事件响应流程流程,通过我们熟悉的使用方法来深入到EventBus的实现内部并理解其实现原理.

创建EventBus

EventBus 类负责所有对外暴露的 API,其中的 register()、post()、unregister() 函数配合上自定义的 EventType 及事件响应函数即可完成核心功能

一般情况下我们都是通过EventBus.getDefault()获取到EventBus对象,进入源码查看其实现:

   public static EventBus getDefault() 
        if(defaultInstance == null) 
            Class var0 = EventBus.class;
            synchronized(EventBus.class) 
                if(defaultInstance == null) 
                    defaultInstance = new EventBus();
                
            
        

        return defaultInstance;
    

这里获得对象的模式是常用的单例模式了,目的是为了保证getDefault()得到的都是同一个实例。如果不存在实例,则会调用EventBus的构造方法:

private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();

  public static EventBusBuilder builder() 
        return new EventBusBuilder();
    



   EventBus(EventBusBuilder builder) 
        this.currentPostingThreadState = new ThreadLocal() 
            protected EventBus.PostingThreadState initialValue() 
                return new EventBus.PostingThreadState();
            
        ;
            //key:订阅的事件,value:订阅这个事件的所有订阅者集合
            //private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
            subscriptionsByEventType = new HashMap<>();
            //key:订阅者对象,value:这个订阅者订阅的事件集合
            //private final Map<Object, List<Class<?>>> typesBySubscriber;
            typesBySubscriber = new HashMap<>();
            //粘性事件 key:粘性事件的class对象, value:事件对象
            //private final Map<Class<?>, Object> stickyEvents;
            stickyEvents = new ConcurrentHashMap<>();
            //事件主线程处理
            mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
            //事件 Background 处理
            backgroundPoster = new BackgroundPoster(this);
            //事件异步线程处理
            asyncPoster = new AsyncPoster(this);
            indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
            //订阅者响应函数信息存储和查找类
            subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
            builder.strictMethodVerification, builder.ignoreGeneratedIndex);
            logSubscriberExceptions = builder.logSubscriberExceptions;
            logNoSubscriberMessages = builder.logNoSubscriberMessages;
            sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
            sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
            throwSubscriberException = builder.throwSubscriberException;
            //是否支持事件继承
            eventInheritance = builder.eventInheritance;
            executorService = builder.executorService;
            //此处参考http://www.jianshu.com/p/f057c460c77e
  

从上面代码可以看出EventBus通过初始化一个EventBusBuilder()对象来初始化EventBus的一些配置。

订阅者的注册

 在获取到EventBus对象以后,我们就可以将订阅者注册到EventBus中。

register()方法的实现

  public void register(Object subscriber) 
        //首先获得订阅者的class对象
        Class subscriberClass = subscriber.getClass();
        /通过subscriberMethodFinder来找到订阅者订阅了哪些事件.返回一个SubscriberMethod对象的List,SubscriberMethod
        //里包含了这个方法的Method对象,以及将来响应订阅是在哪个线程的ThreadMode
        //以及订阅的事件类型eventType,以及订阅的优
        //先级priority,以及是否接收粘性sticky事件的boolean值.
        List subscriberMethods = this.subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized(this) 
            Iterator var5 = subscriberMethods.iterator();

            while(var5.hasNext()) 
                SubscriberMethod subscriberMethod = (SubscriberMethod)var5.next();
                //订阅
                this.subscribe(subscriber, subscriberMethod);
            

        
    

SubscriberMethodFinder类就是用来查找和缓存订阅者响应函数的信息的类。

3.0版本中,EventBus提供了一个EventBusAnnotationProcessor注解处理器来在编译期通过读取@Subscribe()注解并解析,处理其中所包含的信息,然后生成java类来保存所有订阅者关于订阅的信息,这样就比在运行时使用反射来获得这些订阅者的信息速度要快.

SubscriberMethod里包含了需要执行subscribe()的信息,下面进入findSubscriberMethods()方法源码中查看:



    List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) 
    //先从METHOD_CACHE取看是否有缓存,key:保存订阅类的类名,value:保存类中订阅的方法数据,
    List subscriberMethods = (List)METHOD_CACHE.get(subscriberClass);
    if(subscriberMethods != null) 
        return subscriberMethods;
     else 
        //是否忽略注解器生成的MyEventBusIndex类
        if(this.ignoreGeneratedIndex) 
            //利用反射来读取订阅类中的订阅方法信息
            subscriberMethods = this.findUsingReflection(subscriberClass);
         else 
            subscriberMethods = this.findUsingInfo(subscriberClass);
        

        if(subscriberMethods.isEmpty()) 
            throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation");
         else 
            //保存进METHOD_CACHE缓存
            METHOD_CACHE.put(subscriberClass, subscriberMethods);
            return subscriberMethods;
        
    

下面我们来看findUsingInfo()方法的源码实现:


    private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) 
        SubscriberMethodFinder.FindState findState = this.prepareFindState();
        //FindState 用来做订阅方法的校验和保存
        findState.initForSubscriber(subscriberClass);

        for(; findState.clazz != null; findState.moveToSuperclass()) 
            findState.subscriberInfo = this.getSubscriberInfo(findState);
            if(findState.subscriberInfo != null) 
                SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
                SubscriberMethod[] var4 = array;
                int var5 = array.length;

                for(int var6 = 0; var6 < var5; ++var6) 
                    SubscriberMethod subscriberMethod = var4[var6];
                    if(findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) 
                        findState.subscriberMethods.add(subscriberMethod);
                    
                
             else 
                this.findUsingReflectionInSingleClass(findState);
            
        

        return this.getMethodsAndRelease(findState);
    

findUsingInfo是通过查找我们上面所说的EventBusIndex类中的信息,来转换成List从而获得订阅类的相关订阅函数的各种信息.

接着让我们进入findUsingReflection()方法:


  private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) 
        SubscriberMethodFinder.FindState findState = this.prepareFindState();
        findState.initForSubscriber(subscriberClass);

        while(findState.clazz != null) 
            //通过反射来获得订阅方法信息
            this.findUsingReflectionInSingleClass(findState);
             //查找父类的订阅方法
            findState.moveToSuperclass();
        
        //获取findState中的SubscriberMethod(订阅方法List)并返回
        return this.getMethodsAndRelease(findState);
    

FindState类做订阅方法的校验和保存,FIND_STATE_POOL静态数组来保存FindState对象,FindState复用,避免重复创建过多的对象.最终通过findUsingReflectionInSingleClass()来具体获得相关订阅方法的信息:

    private void findUsingReflectionInSingleClass(SubscriberMethodFinder.FindState findState) 
        Method[] methods;
        try 
            //获得声明的所有方法
            methods = findState.clazz.getDeclaredMethods();
         catch (Throwable var12) 
            //异常则获取公开方法
            methods = findState.clazz.getMethods();
            findState.skipSuperClasses = true;
        

        Method[] th = methods;
        int var4 = methods.length;

        for(int var5 = 0; var5 < var4; ++var5) 
            Method method = th[var5];
            //返回int类型值表示该字段的修饰符
            int modifiers = method.getModifiers();
            if((modifiers & 1) != 0 && (modifiers & 5192) == 0) 
                Class[] var13 = method.getParameterTypes();
                if(var13.length == 1) 
                    Subscribe methodName1 = (Subscribe)method.getAnnotation(Subscribe.class);
                    if(methodName1 != null) 
                        Class eventType = var13[0];
                        if(findState.checkAdd(method, eventType)) 
                            ThreadMode threadMode = methodName1.threadMode();
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, methodName1.priority(), methodName1.sticky()));
                        
                    
                 else if(this.strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) 
                    String var14 = method.getDeclaringClass().getName() + "." + method.getName();
                    throw new EventBusException("@Subscribe method " + var14 + "must have exactly 1 parameter but has " + var13.length);
                
             else if(this.strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) 
                String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                throw new EventBusException(methodName + " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
            
        

    

至此,在register()方法中,订阅类的所有SubscriberMethod都已经被保存了,最后再通过getMethodsAndRelease()返回List。

接着,我们查看register()方法中的订阅事件

      synchronized(this) 
            //获取到所有的订阅方法,一一订阅
           Iterator var5 = subscriberMethods.iterator();
            while(var5.hasNext()) 
               SubscriberMethod subscriberMethod = (SubscriberMethod)var5.next();
               this.subscribe(subscriber, subscriberMethod);
           

       

进入subscribe(subscriber, subscriberMethod);源码查看下。


  private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) 
        ////获取订阅的事件类型 普通事件和粘性事件
        Class eventType = subscriberMethod.eventType;
        ////创建Subscription对象
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        //从subscriptionsByEventType里检查是否已经添加过该Subscription
        CopyOnWriteArrayList subscriptions = (CopyOnWriteArrayList)this.subscriptionsByEventType.get(eventType);
        if(subscriptions == null) 
            //未添加则创建
            subscriptions = new CopyOnWriteArrayList();
            this.subscriptionsByEventType.put(eventType, subscriptions);
         else if(subscriptions.contains(newSubscription)) 
            //如果添加过就抛出异常
            throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event " + eventType);
        
        //根据优先级priority来添加Subscription对象
        int size = subscriptions.size();

        for(int subscribedEvents = 0; subscribedEvents <= size; ++subscribedEvents) 
            if(subscribedEvents == size || subscriberMethod.priority > ((Subscription)subscriptions.get(subscribedEvents)).subscriberMethod.priority) 
                subscriptions.add(subscribedEvents, newSubscription);
                break;
            
        
        //将订阅者对象以及订阅的事件保存到typesBySubscriber里.
        //  private final Map<Object, List<Class<?>>> typesBySubscriber
        Object var13 = (List)this.typesBySubscriber.get(subscriber);
        if(var13 == null) 
            var13 = new ArrayList();
            this.typesBySubscriber.put(subscriber, var13);
        

        ((List)var13).add(eventType);
        //如果事件的类型是sticky,则立即分发sticky事件
        if(subscriberMethod.sticky) 
            if(this.eventInheritance) 
                //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 stickyEvent = this.stickyEvents.entrySet();
                Iterator var9 = stickyEvent.iterator();

                while(var9.hasNext()) 
                    Entry entry = (Entry)var9.next();
                    Class candidateEventType = (Class)entry.getKey();
                    if(eventType.isAssignableFrom(candidateEventType)) 
                        Object stickyEvent1 = entry.getValue();
                        //分发sticky事件给订阅者
                        this.checkPostStickyEventToSubscription(newSubscription, stickyEvent1);
                    
                
             else 
                Object var14 = this.stickyEvents.get(eventType);
                //分发sticky事件给订阅者
                this.checkPostStickyEventToSubscription(newSubscription, var14);
            
        

    

下面抄图展示register() 函数流程:

事件分发过程源码分析(post与postSticky)

    public void postSticky(Object event) 
          //最终会调用post(Object event)
          Map var2 = this.stickyEvents;
          synchronized(this.stickyEvents) 
              //将event放入 private final Map<Class<?>, Object> stickyEvents的map中
              this.stickyEvents.put(event.getClass(), event);
          

          this.post(event);
      

    public void post(Object event) 
         //得到当前线程的postingState状态
        EventBus.PostingThreadState postingState = (EventBus.PostingThreadState)this.currentPostingThreadState.get();
        //获取当前线程的事件队列
        List eventQueue = postingState.eventQueue;
        eventQueue.add(event);
        if(!postingState.isPosting) 
            //判断是否是主线程
            postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
            postingState.isPosting = true;
            if(postingState.canceled) 
                throw new EventBusException("Internal error. Abort state was not reset");
            

            try 
                while(!eventQueue.isEmpty()) 
                    //若果不是空,则分发事件
                    this.postSingleEvent(eventQueue.remove(0), postingState);
                
             finally 
                postingState.isPosting = false;
                postingState.isMainThread = false;
            
        

    

currentPostingThreadState的实现是一个包含了PostingThreadState的ThreadLocal对象

private final ThreadLocal<EventBus.PostingThreadState> currentPostingThreadState;

 EventBus(EventBusBuilder builder) 
        this.currentPostingThreadState = new ThreadLocal() 
            protected EventBus.PostingThreadState initialValue() 
                return new EventBus.PostingThreadState();
            
        ;
   

PostingThreadState类如下:

  static final class PostingThreadState 
        final List<Object> eventQueue = new ArrayList();
        boolean isPosting;
        boolean isMainThread;
        Subscription subscription;
        Object event;
        boolean canceled;

        PostingThreadState() 
        
    

ThreadLocal用于实现在不同的线程中存储线程私有数据的类。在多线程的环境中,当多个线程需要对某个变量进行频繁操作,同时各个线程间不需要同步,此时,各个子线程只需要对存储在当前线程中的变量的拷贝进行操作即可,程序的运行效率会很高,即所谓的空间换时间。

Android版的ThreadLocal和java原生的ThreadLocal有一定的差别,android版的进行了一些优化设计,通过内部类Values中的Object数组来存储ThreadLocal的弱引用和线程的局部数据对象;而java版的是以MAP的方式来存储。

具体请查看Android开发之ThreadLocal原理深入理解

接下来我们进入postSingleEvent(eventQueue.remove(0), postingState)去查看:

          try 
                while(!eventQueue.isEmpty()) 
                    this.postSingleEvent(eventQueue.remove(0), postingState);
                
             finally 
                postingState.isPosting = false;
                postingState.isMainThread = false;
            

postSingleEvent(eventQueue.remove(0), postingState)包含的几个主要方法一并列出:

    private void postSingleEvent(Object event, EventBus.PostingThreadState postingState) throws Error 
        Class eventClass = event.getClass();
        boolean subscriptionFound = false;
        //是否触发订阅了该事件(eventClass)的父类,以及接口的类的响应方法.
        if(this.eventInheritance) 
            //查找eventClass类所有的父类以及接口
            List eventTypes = lookupAllEventTypes(eventClass);
            int countTypes = eventTypes.size();

            for(int h = 0; h < countTypes; ++h) 
                Class clazz = (Class)eventTypes.get(h);
                //右边有一个为true,subscriptionFound属性为true
                subscriptionFound |= this.postSingleEventForEventType(event, postingState, clazz);
            
         else 
            //post单个事件
            subscriptionFound = this.postSingleEventForEventType(event, postingState, eventClass);
        

        if(!subscriptionFound) 
            //如果未发现
            if(this.logNoSubscriberMessages) 
                Log.d(TAG, "No subscribers registered for event " + eventClass);
            

            if(this.sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) 
              //满足上述条件则发送空事件
                this.post(new NoSubscriberEvent(this, event));
            
        

    

    private boolean postSingleEventForEventType(Object event, EventBus.PostingThreadState postingState, Class<?> eventClass) 
        CopyOnWriteArrayList subscriptions;
        synchronized(this) 
          //获取订阅了这个事件的Subscription列表.
            subscriptions = (CopyOnWriteArrayList)this.subscriptionsByEventType.get(eventClass);
        

        if(subscriptions != null && !subscriptions.isEmpty()) 
            Iterator var5 = subscriptions.iterator();

            while(var5.hasNext()) 
                Subscription subscription = (Subscription)var5.next();
                postingState.event = event;
                postingState.subscription = subscription;
                boolean aborted = false;

                try 
                    //一个个将事件分发给订阅者
                    this.postToSubscription(subscription, event, postingState.isMainThread);
                    aborted = postingState.canceled;
                 finally 
                    //将postingState置为初始状态
                    postingState.event = null;
                    postingState.subscription = null;
                    postingState.canceled = false;
                

                if(aborted) 
                  //如果被中断,结束整个循环体
                    break;
                
            

            return true;
         else 
            return false;
        
    


  //postToSubscription()通过不同的threadMode在不同的线程里invoke()订阅者的方法
    private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) 
        switch(null.$SwitchMap$com$inno$eventbus$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);
        

    

    //通过反射调用了订阅者的订阅函数并把event对象作为参数传入
    void invokeSubscriber(Subscription subscription, Object event) 
            try 
                subscription.subscriberMethod.method.invoke(subscription.subscriber, new Object[]event);
             catch (InvocationTargetException var4) 
                this.handleSubscriberException(subscription, event, var4.getCause());
             catch (IllegalAccessException var5) 
                throw new IllegalStateException("Unexpected exception", var5);
            
  

ThreadMode共有四类:

  • PostThread:默认的 ThreadMode,表示在执行 Post 操作的线程直接调用订阅者的事件响应方法,不论该线程是否为主线程(UI 线程)。当该线程为主线程时,响应方法中不能有耗时操作,否则有卡主线程的风险。适用场景:对于是否在主线程执行无要求,但若 Post 线程为主线程,不能耗时的操作;
  • MainThread:在主线程中执行响应方法。如果发布线程就是主线程,则直接调用订阅者的事件响应方法,否则通过主线程的 Handler 发送消息在主线程中处理——调用订阅者的事件响应函数。显然,MainThread类的方法也不能有耗时操作,以避免卡主线程。适用场景:必须在主线程执行的操作;
  • BackgroundThread:在后台线程中执行响应方法。如果发布线程不是主线程,则直接调用订阅者的事件响应函数,否则启动唯一的后台线程去处理。由于后台线程是唯一的,当事件超过一个的时候,它们会被放在队列中依次执行,因此该类响应方法虽然没有PostThread类和MainThread类方法对性能敏感,但最好不要有重度耗时的操作或太频繁的轻度耗时操作,以造成其他操作等待。适用场景:操作轻微耗时且不会过于频繁,即一般的耗时操作都可以放在这里;
  • Async:不论发布线程是否为主线程,都使用一个空闲线程来处理。和BackgroundThread不同的是,Async类的所有线程是相互独立的,因此不会出现卡线程的问题。适用场景:长耗时操作,例如网络访问。
    引用地址

post()整体流程图如下

EventBus解除注册源码分析

解除注册只要调用unregister()方法即可实现

   public synchronized void unregister(Object subscriber) 
     //通过typesBySubscriber来取出这个subscriber订阅者订阅的事件类型,
        List subscribedTypes = (List)this.typesBySubscriber.get(subscriber);
        if(subscribedTypes != null) 
          //如果不是null
            Iterator var3 = subscribedTypes.iterator();

            while(var3.hasNext()) 
                Class eventType = (Class)var3.next();
                //分别解除每个订阅了的事件类型
                this.unsubscribeByEventType(subscriber, eventType);
            

            this.typesBySubscriber.remove(subscriber);
         else 
            Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
        

    

    private void unsubscribeByEventType(Object subscriber, Class<?> eventType) 
          List subscriptions = (List)this.subscriptionsByEventType.get(eventType);
          //subscriptionsByEventType里拿出这个事件类型的订阅者列表.
          if(subscriptions != null) 
              int size = subscriptions.size();

              for(int i = 0; i < size; ++i) 
                //分别取消订阅
                  Subscription subscription = (Subscription)subscriptions.get(i);
                  if(subscription.subscriber == subscriber) 
                      subscription.active = false;
                      subscriptions.remove(i);
                      --i;
                      --size;
                  
              
          

      

从上面代码可以看出最终从typesBySubscriber和subscriptions里分别移除订阅者以及相关信息,完成反注册.

源码已经进行了简单的分析,而且EventBus的总体积大小是52K,总体来看EventBus还是很值得我们在项目中使用的。尽快使用它吧!

EventBus3.0jar包下载地址

以上是关于EventBus3.0源码浅析与理解的主要内容,如果未能解决你的问题,请参考以下文章

EventBus3.0源码解读

EventBus3.0源码解析

EventBus3.0源码分析

EventBus3.0源码分析

EventBus3.0源码分析

EventBus3.0源码解析——06. 总结