EventBus源码分析

5 篇文章 0 订阅
2 篇文章 0 订阅
前言

分析Android源码确实挺累人的,看着看着就会丧失部分当初坚持要看下去的决心,但是又不能懈怠,所以源码的分心先缓一缓,不能产生一种对源码的厌恶感,这是很可怕的,所以为了保留仅剩的好奇心,选择了一个三方的框架来分析一下,换换脑子,这期间也有助于重新唤起分析Android源码的那份冲劲,学习道路上的绊脚石真的太多来,任何东西都可能对你使绊,所以我们在前进的过程中,要摸索出一套自己的方法论来克服这些困难,我目前的方法就是看腻来的只是可能先放一放,不要彻底丧失那份兴趣,可以换个知识点胡子和干点别的,这样可能会好点。所以才有这片文章。


EvenBus的使用就不介绍来,相信大家都知道如何使用,下面仅从实现原理和源码角度来分析一下,但是有几个注意事项需要注意一下。

  1. 几个注意事项
  • 订阅方法的参数类型必须是引用类型
  @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(int value) {
        System.out.println("value = [" + value + "]");
    }
    //int 是不行的,必须是他的包装类型:Integer
  • 一个类可以有多个订阅的方法
  • 有可能一个类中,订阅的方法参数一样,但是方法名字不一样
参数都是Integer,但是方法名字不一样
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(Integer value) {
        System.out.println("value = [" + value + "]");
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent1(Integer value) {
        System.out.println("value = [" + value + "]");
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent2(Integer value) {
        System.out.println("value = [" + value + "]");
    }

  • 注册订阅方法的时候会根据注解中的priority属性对方法进行优先级的排序。

先分析一下EventBus对象的创建过程,EventBus是一个单例对象,由于他的初始化用到的参数比较多,所以使用类常用的Builder模式创建。

public class EventBus {

     private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder(){
         this(DEFAULT_BUILDER);
     };
      
      //对后面用到的一些参数初始化。
      EventBus(EventBusBuilder builder) {
        subscriptionsByEventType = new HashMap<>();
        typesBySubscriber = new HashMap<>();
        stickyEvents = new ConcurrentHashMap<>();
        mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
        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;
    }

    }
    
    public class EventBusBuilder {
    private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();

    boolean logSubscriberExceptions = true;
    boolean logNoSubscriberMessages = true;
    boolean sendSubscriberExceptionEvent = true;
    boolean sendNoSubscriberEvent = true;
    boolean throwSubscriberException;
    boolean eventInheritance = true;
    boolean ignoreGeneratedIndex; //这个参数默认false,主要是用来区分是否使用类注解处理器获取订阅方法的,这里值分析通过反射获取。
    boolean strictMethodVerification;
    ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
    List<Class<?>> skipMethodVerificationForClasses;
    List<SubscriberInfoIndex> subscriberInfoIndexes;

    EventBusBuilder() {
    }
}
    

注册的过程分两步进行

  1. 先找到要注册的方法
 public void register(Object subscriber) {
        Class<?> subscriberClass = subscriber.getClass();
        //根据注册类的Class对象获取要注册的方法。参见1.1
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

1.1 反射获取订阅的方法,这个步骤里面有一个缓存METHOD_CACHE,他的key是订阅类的Class对象,value是一个List,里面装的就是当前类所有被Subscribe注解的方法,因为反射是比较消耗性能的,没次都去反射获取调用的方法有损性能,所以找到所有的订阅方法后会做一个缓存,如果这个类之前已经注册过了,就直接返回已经注册的方法。

 List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }
        //通过上面知道ignoreGeneratedIndex = false
        if (ignoreGeneratedIndex) {
             参见1.2
            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 {
        //会把找到的方法缓存起来。
            METHOD_CACHE.put(subscriberClass, subscriberMethods);
            return subscriberMethods;
        }
    }

1.2

 private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
        FindState findState = prepareFindState();参见1.3
        //初始化FindState的一些成员变量,主要是把订阅类的class对象传进去了
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
        //没有用注解的话,subscriberInfo == null,所以会走else分支
            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 {
                参见1.4
                findUsingReflectionInSingleClass(findState);
            }
            //把class对象指向父类继续寻找订阅方法
            findState.moveToSuperclass();
        }
        //释放FindState到缓存池里。
        return getMethodsAndRelease(findState);
    }

1.3 这里有一个FindState的缓存池,用来获取FindState对象,首次组册的时候FIND_STATE_POOL是空的,会new一个FindState,然后再使用完以后会把这个新的FindState放到FIND_STATE_POOL缓存池里面,方便后面复用。

 private FindState prepareFindState() {
        synchronized (FIND_STATE_POOL) {
            for (int i = 0; i < POOL_SIZE; i++) {
                FindState state = FIND_STATE_POOL[i];
                如果缓存池里有的话会复用。
                if (state != null) {
                    FIND_STATE_POOL[i] = null;
                    return state;
                }
            }
        }
        //缓存池为空,会创建一个,在使用完通过getMethodsAndRelease方法中会放到FIND_STATE_POOL中。
        return new FindState();
    }
static class FindState { 
        //里面装的是订阅的方法
        final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
        //key是订阅方法的参数的class对象,value是方法或者方法的封装SubscriberMethod
        final Map<Class, Object> anyMethodByEventType = new HashMap<>();
        //key是订阅的方法签名,value是订阅类的class对象。
        final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
        final StringBuilder methodKeyBuilder = new StringBuilder(128);

1.4

  private void findUsingReflectionInSingleClass(FindState findState) {
        Method[] methods;
        try {
            //这个只会拿到当前类定义和重写的一些方法,并不会去把所有继承链上的方法拿出来。
            //当低设备的手机上访问高版本的api的时候这个方法在可能会抛出异常,所以在catch中我们会获取所有的方法。
            methods = findState.clazz.getDeclaredMethods();
        } catch (Throwable th) {
            // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
            methods = findState.clazz.getMethods();
            findState.skipSuperClasses = true;
        
        //遍历找到Subscribe注解的方法。循环结束以后就会找到所有订阅的方法方法
        for (Method method : methods) {
            int modifiers = method.getModifiers();
            if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length == 1) {
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                    if (subscribeAnnotation != null) {
                    //获取订阅方法的参数
                        Class<?> eventType = parameterTypes[0];
                        参见1.4
                        if (findState.checkAdd(method, eventType)) {
                            ThreadMode threadMode = subscribeAnnotation.threadMode();
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                    subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                        }
                    }
                } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                    String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                    throw new EventBusException("@Subscribe method " + methodName +
                            "must have exactly 1 parameter but has " + parameterTypes.length);
                }
            } else if (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");
            }
        }
    }

1.5

boolean checkAdd(Method method, Class<?> eventType) {
            //检查eventType类型参数的订阅方法是否已经存在
            Object existing = anyMethodByEventType.put(eventType, method);
            if (existing == null) {
                return true;//不存在返回true,会添加到subscriberMethods的map里面
            } else {
             //  已经有evetType参数类型的方法,经过下面if的逻辑处理,
             //会把这个方法封装成SubscriberMethodFinder类型,
             //如果evetType参数类型的方法有多个,因为第一次已经改变的existing
             //的类型,所以直接跳过if的逻辑
             
             //existing的变化
             //第一次existing ->Method, 第二次,第一次existing -> SubscriberMethodFinder
            
                if (existing instanceof Method) {
                //如果存在,再根据方法签名检查订阅的类是不是存在。参见1.6
                    if (!checkAddWithMethodSignature((Method) existing, eventType)) {
                     
                        throw new IllegalStateException();
                    }
                    //把已经存在的方法重新打包封装成SubscriberMethodFinder存进来,下次如果有参数类型一样的方法,就会跳过这部分逻辑,直接通过签名验证以后添加
                    anyMethodByEventType.put(eventType, this);
                }
                return checkAddWithMethodSignature(method, eventType);
            }
        }

1.6 这里涉及到类的方法签名,在Java中唯一确定一个方法的依据是方法的名字和方法的参数,返回值是不参与方法签名的

  private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
            methodKeyBuilder.setLength(0);
            //拼接方法名字和参数的名字
            methodKeyBuilder.append(method.getName());
            methodKeyBuilder.append('>').append(eventType.getName());
            
            
            //methodKey可以唯一代表一个类中的某个方法,
            String methodKey = methodKeyBuilder.toString();
            Class<?> methodClass = method.getDeclaringClass();
            Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);
            //methodClassOld永远是false,因为一个类中不可能出先方法签名一样的方法,
            if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
                // Only add if not already found in a sub class
                return true;
            } else {
                // Revert the put, old class is further down the class hierarchy
                subscriberClassByMethodKey.put(methodKey, methodClassOld);
                return false;
            }
        }
  1. 找到要注册的方法后才去真真的执行订阅操作

    2.1 注册其实就是一个subscribe方法,只不过是在循环中重复调用组册的,post事件的时候其实是从subscriptionsByEventTyp的map里拿的订阅方法。

  private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
        //获取订阅方法的参数类型
        Class<?> eventType = subscriberMethod.eventType;
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        //获取参数类型所对应的参数方法,注意事项中已经说过。
        //同一个参数类型,可能有多个订阅的方法,虽然实际情况很少这样使用。
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        //没找到创建并添加进subscriptionsByEventType
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList<>();
            subscriptionsByEventType.put(eventType, subscriptions);
        } else {
            if (subscriptions.contains(newSubscription)) {
                throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                        + eventType);
            }
        }

//这里是对形同参数类型的方法根据priority进行排序。
        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;
            }
        }
 //根据订阅类找到这个类中的订阅的方法,下面的逻辑主要是为判断某个类是否已经注册过或者对外提供一些api。
 //eg:isRegistered(Object subscriber),unregister(Object subscriber)...
        List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
        if (subscribedEvents == null) {
            subscribedEvents = new ArrayList<>();
            typesBySubscriber.put(subscriber, 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);
            }
        }
    }
  1. 下面就是事件的分发里。
EventBus.getDefault().post(66666);//分发一个Integer类型的事件。
    public void post(Object event) {
    //获取当前线程的事件队列。ThreadLocal可以是每个线程拥有自己的事件队列
        PostingThreadState postingState = currentPostingThreadState.get();
        List<Object> 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()) {
                //参见3.1
                    postSingleEvent(eventQueue.remove(0), postingState);
                }
            } finally {
                postingState.isPosting = false;
                postingState.isMainThread = false;
            }
        }
    }

3.1 postSingleEvent分发有两个步骤

  1. 找到分发事件的继承链上的所有class对象
  2. 遍历第一步的中找到的所有class集合,找到该class的所有已订阅的分发
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
        Class<?> eventClass = event.getClass();
        boolean subscriptionFound = false;
        if (eventInheritance) {
        //找到eventClass的简介或者直接的夫类class对象和所实现的接口class对象
        //会一直找到Object为止。
            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);参见3.2
            }
        } 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));
            }
        }
    }

3.2 更具发送事件的Class找到该Class的所有订阅的分发

 private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
        CopyOnWriteArrayList<Subscription> subscriptions;
        synchronized (this) {
        //根据class从订阅的Map中找订阅的分发
            subscriptions = subscriptionsByEventType.get(eventClass);
        }
        if (subscriptions != null && !subscriptions.isEmpty()) {
        //找到后遍历调用订阅的分发
            for (Subscription subscription : subscriptions) {
                postingState.event = event;
                postingState.subscription = subscription;
                boolean aborted = false;
                try {
                    //参见3.3
                    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;
    }

3.3根据订阅分发期望的线程和分发事件的线程发送事件

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 {
                   //非主线程分发的,参见3.4
                    mainThreadPoster.enqueue(subscription, event);
                }
                break;
            case BACKGROUND:
                if (isMainThread) {
                    //参见3.5
                    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);
        }
    }

3.3.1结社我们来分析一下PendingPost这个类

final class PendingPost {
    //缓存池,最大数量是10000个
    private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();

    Object event;//消息
    Subscription subscription; //订阅分方法和订阅类的封装
    PendingPost next;//用来实现的队列的。

    private PendingPost(Object event, Subscription subscription) {
        this.event = event;
        this.subscription = subscription;
    }


//类似于Android中的Messager#obtain方法,缓存中有就直接那,没有用完后放到缓存中
    static PendingPost obtainPendingPost(Subscription subscription, Object event) {
        synchronized (pendingPostPool) {
            int size = pendingPostPool.size();
            if (size > 0) {
                PendingPost pendingPost = pendingPostPool.remove(size - 1);
                pendingPost.event = event;
                pendingPost.subscription = subscription;
                pendingPost.next = null;
                return pendingPost;
            }
        }
        return new PendingPost(event, subscription);
    }

//1.释放资源
//2. 放入缓存中
    static void releasePendingPost(PendingPost pendingPost) {
        pendingPost.event = null;
        pendingPost.subscription = null;
        pendingPost.next = null;
        synchronized (pendingPostPool) {
            // Don't let the pool grow indefinitely
            if (pendingPostPool.size() < 10000) {
                pendingPostPool.add(pendingPost);
            }
        }
    }

}

3.3.2PendingPostQueue是一个简单的实现,用的是链表的实方式。

final class PendingPostQueue {
    private PendingPost head;//队列的头
    private PendingPost tail;//链表的尾

    synchronized void enqueue(PendingPost pendingPost) {
        if (pendingPost == null) {
            throw new NullPointerException("null cannot be enqueued");
        }
        if (tail != null) {//tail已经存在了,把pendingPost放到队尾。
            tail.next = pendingPost;
            tail = pendingPost;
        } else if (head == null) {//队列空的时候创建队列的头和尾
            head = tail = pendingPost;
        } else {
            throw new IllegalStateException("Head present, but no tail");
        }
        notifyAll();
    }
//出队操作。
    synchronized PendingPost poll() {
        PendingPost pendingPost = head;
        if (head != null) {
            head = head.next;
            if (head == null) {
                tail = null;
            }
        }
        return pendingPost;
    }

    synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {
        if (head == null) {
            wait(maxMillisToWait);
        }
        return poll();
    }

}

3.4内部通过Handler和消息队列类处理的,

 void enqueue(Subscription subscription, Object event) {
       //从PendingPost的缓存中拿到一个将要发送到主线的pendingPost,这个缓存的最大数据量是10000个。
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
        //放到消息队列中
            queue.enqueue(pendingPost);
            if (!handlerActive) {
                handlerActive = true;
                发送Messager处理队列中的消息
                if (!sendMessage(obtainMessage())) {
                    throw new EventBusException("Could not send handler message");
                }
            }
        }
    }
    
     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;
                //不过这里需要注意的是EventBus为HandlerPoster处理调用注册
                //设定了时间上限,
                //也就是构造器中初始化的maxMillisInsideHandleMessage,
                //在EventBus中初始化mainThreadPost时为其指定了10ms,
                //也就是while循环超过10ms之后会退出handleMessage方法,
                //并将handleActive置位true,并再次发送消息,
                //使得该handler再次调用handleMessage()方法,继续处理队列中的//注册信息,这是为了避免队列过长是,
                //while循环阻塞主线程造成卡顿。
                if (timeInMethod >= maxMillisInsideHandleMessage) {
                    if (!sendMessage(obtainMessage())) {
                        throw new EventBusException("Could not send handler message");
                    }
                    rescheduled = true;
                    return;
                }
            }
        } finally {
            handlerActive = rescheduled;
        }
    }

3.5订阅分发在子线程中分发
3.5.1 先看一下BackgroundPoster,是一个runable对象,用来在子线程中调用方法

final class BackgroundPoster implements Runnable {

    private final PendingPostQueue queue;
    private final EventBus eventBus;

    private volatile boolean executorRunning;

    BackgroundPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            queue.enqueue(pendingPost);
            if (!executorRunning) {
                executorRunning = true;//只会创建一个子线程,所有的消息都在同一个线程这个处理
                eventBus.getExecutorService().execute(this);
            }
        }
    }

    @Override
    public void run() {
        try {
            try {
            //循环♻️在子线程中调用分发。
                while (true) {
                    PendingPost pendingPost = queue.poll(1000);
                    if (pendingPost == null) {
                        synchronized (this) {
                            // Check again, this time in synchronized
                            pendingPost = queue.poll();
                            if (pendingPost == null) {
                                executorRunning = false;
                                return;
                            }
                        }
                    }
                    eventBus.invokeSubscriber(pendingPost);
                }
            } catch (InterruptedException e) {
                Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);
            }
        } finally {
            executorRunning = false;
        }
    }

}

class AsyncPoster implements Runnable {

    private final PendingPostQueue queue;
    private final EventBus eventBus;

    AsyncPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        queue.enqueue(pendingPost);//没次都会创建一个线程来运行订阅的分发。
        eventBus.getExecutorService().execute(this);
    }

    @Override
    public void run() {
        PendingPost pendingPost = queue.poll();
        if(pendingPost == null) {
            throw new IllegalStateException("No pending post available");
        }
        eventBus.invokeSubscriber(pendingPost);
    }

}

BackgroundPoster类,虽然也实现了Runnable接口,虽然也在子线程中执行EventBus的反射回调方法。但是与AsyncPoster类不同的是:

  1. AsyncPoster类每次任务都会新建一个线程,并发执行队列中的任务
  2. 而BackgroundPoster类只会新建一个子线程,队列中的任务,只会顺序执行。

到这里就分析完来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值