greenrobot的EventBus 源码解析

上篇是EventBus的使用和概述,EventBus源码可以在github:https://github.com/greenrobot/EventBus
进行下载:
下面我们看EventBus怎么实现的原码。
在我们使用的时候 首先要注册:
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;
    }

为了提高效率,声明了一个单例的模式。
再看register()方法

public void register(Object subscriber) {
// 注册对象 一般 为this
 Class<?> subscriberClass = subscriber.getClass();
 // activity
 List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); 
 // 获取activity的方法集合
  synchronized (this ) {
  for (SubscriberMethod subscriberMethod : subscriberMethods) {
         subscribe(subscriber, subscriberMethod);
             }
         }
    }

进行对象的注册 进行通过反射查找订阅的方法集合。

private final SubscriberMethodFinder subscriberMethodFinder ;
SubscriberMethodFinder 类 进行方法查找通过反射的方式
/** 获取对象的中 的方法 */
 List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
         List<SubscriberMethod> subscriberMethods = METHOD_CACHE
                 .get(subscriberClass); // 查看缓存是否包含该对象 Map<Class<?>, List<SubscriberMethod>>
          if (subscriberMethods != null) {
              return subscriberMethods;
         }

          if (ignoreGeneratedIndex ) {
             subscriberMethods = findUsingReflection(subscriberClass);
         } else {
             subscriberMethods = findUsingInfo(subscriberClass);
         }
          if (subscriberMethods.isEmpty()) {
              throw new EventBusException(
                       "Subscriber "
                               + subscriberClass
                               + " ");
         } else {
              METHOD_CACHE.put(subscriberClass, subscriberMethods);
              return subscriberMethods;
         }
    }

最终都会调用findUsingReflectionInSingleClass

/** 通过反射获取methods 注解模式*/

 List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        String key = subscriberClass.getName();
        List<SubscriberMethod> subscriberMethods;
        synchronized (methodCache ) {
            subscriberMethods = methodCache.get(key);
        }
        if (subscriberMethods != null) {
            return subscriberMethods;
        }
        subscriberMethods = new ArrayList<SubscriberMethod>();
        Class<?> clazz = subscriberClass;
        HashSet<String> eventTypesFound = new HashSet<String>();
        StringBuilder methodKeyBuilder = new StringBuilder();
        while (clazz != null) {
            String name = clazz.getName();
            if (name.startsWith("java." ) || name.startsWith("javax." ) || name.startsWith("android." )) {
                // Skip system classes, this just degrades performance
                break;
            }

            // Starting with EventBus 2.2 we enforced methods to be public (might change with annotations again)
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                String methodName = method.getName();
                if (methodName.startsWith(ON_EVENT_METHOD_NAME )) {
                    int modifiers = method.getModifiers();
                    if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE ) == 0) {
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        if (parameterTypes.length == 1) {
                            String modifierString = methodName.substring(ON_EVENT_METHOD_NAME .length());
                            ThreadMode threadMode;
                            if (modifierString.length() == 0) {
                                threadMode = ThreadMode.PostThread ;
                            } else if (modifierString.equals( "MainThread")) {
                                threadMode = ThreadMode.MainThread ;
                            } else if (modifierString.equals( "BackgroundThread")) {
                                threadMode = ThreadMode.BackgroundThread ;
                            } else if (modifierString.equals( "Async")) {
                                threadMode = ThreadMode.Async ;
                            } else {
                                if (skipMethodVerificationForClasses .containsKey(clazz)) {
                                    continue;
                                } else {
                                    throw new EventBusException("Illegal onEvent method, check for typos: " + method);
                                }
                            }
                            Class<?> eventType = parameterTypes[0];
                            methodKeyBuilder.setLength(0);
                            methodKeyBuilder.append(methodName);
                            methodKeyBuilder.append('>' ).append(eventType.getName());
                            String methodKey = methodKeyBuilder.toString();
                            if (eventTypesFound.add(methodKey)) {
                                // Only add if not already found in a sub class
                                subscriberMethods.add(new SubscriberMethod(method, threadMode, eventType));
                            }
                        }
                    } else if (!skipMethodVerificationForClasses .containsKey(clazz)) {
                        Log. d(EventBus.TAG, "Skipping method (not public, static or abstract): " + clazz + "."
                                + methodName);
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
        if (subscriberMethods.isEmpty()) {
            throw new EventBusException("Subscriber " + subscriberClass + " has no public methods called "
                    + ON_EVENT_METHOD_NAME);
        } else {
            synchronized (methodCache ) {
                methodCache.put(key, subscriberMethods);
            }
            return subscriberMethods;
        }
    }

//返回的方法集合进行2次处理
// Must be called in synchronized block
    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
         Class<?> eventType = subscriberMethod.eventType ;// 参数 param类型
         Subscription newSubscription = new Subscription(subscriber,
                 subscriberMethod); // 组合方法和类之间的关系
         CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType
                 .get(eventType);
          if (subscriptions == null) {
             subscriptions = new CopyOnWriteArrayList<Subscription>();
              subscriptionsByEventType.put(eventType, subscriptions);
         } else {
              if (subscriptions.contains(newSubscription)) {
                  throw new EventBusException("Subscriber "
                          + subscriber.getClass()
                          + " already registered to event " + eventType);
             }
         }

          int size = subscriptions.size();
          for (int i = 0; i <= size; i++) {
              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<Class<?>>();
              typesBySubscriber.put(subscriber, subscribedEvents);
         }
         subscribedEvents.add(eventType);

          if (subscriberMethod.sticky ) {
              if (eventInheritance ) {

                 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);
             }
         }
    }

以上是可以定义为收集订阅方法到一个map集合缓存中:

第二就是我们要发布订阅事件过程:

EventBus.getDefault().post(new User("android"));

/** Posts the given event to the event bus. */
    public void post(Object event) {
          // 获取当前线程
         PostingThreadState postingState = currentPostingThreadState .get();
         List<Object> eventQueue = postingState.eventQueue ;
         eventQueue.add(event);

          if (!postingState.isPosting ) {// 是否是UI线程
             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()) {
                     postSingleEvent(eventQueue.remove(0), postingState);
                 }
             } finally {
                 postingState. isPosting = false ;
                 postingState. isMainThread = false ;
             }
         }
    }
private void postSingleEvent(Object event, PostingThreadState postingState)
              throws Error {
         Class<?> eventClass = event.getClass(); // event param 类型
          boolean subscriptionFound = false;
          if (eventInheritance ) {
             List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
              int countTypes = eventTypes.size();
              for (int h = 0; h < countTypes; h++) {
                 Class<?> clazz = eventTypes.get(h);
                 subscriptionFound |= postSingleEventForEventType(event,
                          postingState, clazz);
             }
         } else {
             subscriptionFound = postSingleEventForEventType(event,
                      postingState, eventClass);
         }
          if (!subscriptionFound) {
              if (logNoSubscriberMessages ) {
                 Log. d(TAG, "No subscribers registered for event " + eventClass);
             }
              if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class
                      && eventClass != SubscriberExceptionEvent.class ) {
                 post( new NoSubscriberEvent(this, event));
             }
         }
    }

    // 执行post 订阅事件
    private boolean postSingleEventForEventType(Object event,
             PostingThreadState postingState, Class<?> eventClass) {
         CopyOnWriteArrayList<Subscription> subscriptions;
          synchronized (this ) {
             subscriptions = subscriptionsByEventType .get(eventClass);
         }
          if (subscriptions != null && !subscriptions.isEmpty()) {
              for (Subscription subscription : subscriptions) {
                 postingState. event = event;
                 postingState. subscription = subscription;
                  boolean aborted = false;
                  try {
                     postToSubscription(subscription, event,
                              postingState. isMainThread);
                      aborted = postingState.canceled;
                 } finally {
                      postingState. event = null ;
                      postingState. subscription = null;
                      postingState. canceled = false ;
                 }
                  if (aborted) {
                       break;
                 }
             }
              return true ;
         }
          return false ;
    }

    //执行的反射方法
    private void postToSubscription(Subscription subscription, Object event,
              boolean isMainThread) {
          switch (subscription.subscriberMethod .threadMode ) {
          case POSTING :
             invokeSubscriber(subscription, event);
              break;
          case MAIN :
              if (isMainThread) {
                 invokeSubscriber(subscription, event);
             } else {
                  mainThreadPoster.enqueue(subscription, event);
             }
              break;
          case BACKGROUND :
              if (isMainThread) {
                  backgroundPoster.enqueue(subscription, event);
             } else {
                 invokeSubscriber(subscription, event);
             }
              break;
          case ASYNC :
              asyncPoster.enqueue(subscription, event);
              break;
          default:
              throw new IllegalStateException("Unknown thread mode: "
                      + subscription.subscriberMethod .threadMode );
         }
    }

void invokeSubscriber(Subscription subscription, Object event) {
          try {
//通过反射进行调用 最终执行显示
             subscription. subscriberMethod.method .invoke(
                      subscription. subscriber, event);
         } catch (InvocationTargetException e) {
             handleSubscriberException(subscription, event, e.getCause());
         } catch (IllegalAccessException e) {
              throw new IllegalStateException("Unexpected exception" , e);
         }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值