zoukankan      html  css  js  c++  java
  • Android EventBus源码解析

     项目地址 :https://github.com/greenrobot/EventBus

    这个项目个人感觉就是为了解决回调事件过多的,比方说A函数在做完以后 要调用b类的c函数,那我们通常的做法就是 定义一个接口 然后再A函数所属的类里面注册这个接口。

    然后a函数做完以后 直接调用这个接口即可。但是这种方法写多了以后确实很麻烦,于是EventBus就是用来解决这种场景的。

    和以往一样,我们只解析他的源码,如果你要学习他的用法请自行谷歌。

    我们就从register函数开始说起。

    1  private synchronized void register(Object subscriber, boolean sticky, int priority) {
    2         //这个list就是方法的集合
    3         List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriber.getClass());
    4         //这个循环的目的就是为了用  方法对象 来构造 Subscription对象
    5         for (SubscriberMethod subscriberMethod : subscriberMethods) {
    6             subscribe(subscriber, subscriberMethod, sticky, priority);
    7         }
    8     }

    首先来看一下SubscriberMethod这个类,

     1 /*
     2  * Copyright (C) 2012 Markus Junginger, greenrobot (http://greenrobot.de)
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *      http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15  */
    16 package de.greenrobot.event;
    17 
    18 import java.lang.reflect.Method;
    19 
    20 import android.util.Log;
    21 
    22 /**
    23  * 这个类就是描述方法用的
    24  */
    25 final class SubscriberMethod {
    26     final Method method;
    27     final ThreadMode threadMode;
    28     final Class<?> eventType;
    29     /** Used for efficient comparison */
    30     /**
    31      * 这个methodString 实际上就是用来描述SubscriberMethod对象的,尤其是在重写的equals方法里 起到关键的作用
    32      * 就类似于这种结构
    33      * com.example.administrator.eventbustest.ItemDetailFragment#onEventMainThread(com.example.administrator.eventbustest.Item
    34      *其实也很好理解就是 包名+类名#方法名(参数的类型
    35      * 注意这里参数的类型也是全路径名 包名+类名
    36      */
    37     String methodString;
    38 
    39     SubscriberMethod(Method method, ThreadMode threadMode, Class<?> eventType) {
    40         this.method = method;
    41         this.threadMode = threadMode;
    42         this.eventType = eventType;
    43     }
    44 
    45     @Override
    46     public boolean equals(Object other) {
    47         if (other instanceof SubscriberMethod) {
    48             checkMethodString();
    49             SubscriberMethod otherSubscriberMethod = (SubscriberMethod) other;
    50             otherSubscriberMethod.checkMethodString();
    51             // Don't use method.equals because of http://code.google.com/p/android/issues/detail?id=7811#c6
    52             return methodString.equals(otherSubscriberMethod.methodString);
    53         } else {
    54             return false;
    55         }
    56     }
    57 
    58     private synchronized void checkMethodString() {
    59         if (methodString == null) {
    60             // Method.toString has more overhead, just take relevant parts of the method
    61             StringBuilder builder = new StringBuilder(64);
    62             builder.append(method.getDeclaringClass().getName());
    63             builder.append('#').append(method.getName());
    64             builder.append('(').append(eventType.getName());
    65             methodString = builder.toString();
    66         }
    67     }
    68 
    69     @Override
    70     public int hashCode() {
    71         return method.hashCode();
    72     }
    73 }

    然后我们来看看这个SubscriberMethod对象组成的集合 是怎么构造出来的。

     1 List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
     2         String key = subscriberClass.getName();
     3         List<SubscriberMethod> subscriberMethods;
     4         synchronized (methodCache) {
     5             subscriberMethods = methodCache.get(key);
     6         }
     7       
     8         if (subscriberMethods != null) {
     9             return subscriberMethods;
    10         }
    11         subscriberMethods = new ArrayList<SubscriberMethod>();
    12         Class<?> clazz = subscriberClass;
    13         HashSet<String> eventTypesFound = new HashSet<String>();
    14         StringBuilder methodKeyBuilder = new StringBuilder();
    15         while (clazz != null) {
    16             String name = clazz.getName();
    17             //这个地方判断如果是这些类,那么就直接跳出这个while循环
    18             //注意name的值 也是包名+类名,所以这里就是过滤掉基础的sdk的那些方法
    19             //如果你有引用其他公共lib库的话 你也可以过滤他们的包,
    20             if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
    21                 // Skip system classes, this just degrades performance
    22                 break;
    23             }
    24 
    25             // Starting with EventBus 2.2 we enforced methods to be public (might change with annotations again)
    26             Method[] methods = clazz.getDeclaredMethods();
    27             for (Method method : methods) {
    28                 String methodName = method.getName();
    29                 Log.e("burning", "methodName == " + methodName);
    30                 //只有那些以onEvent开头的方法才是我们需要的
    31                 if (methodName.startsWith(ON_EVENT_METHOD_NAME)) {
    32                     int modifiers = method.getModifiers();
    33                     //注意这个地方判断方法属性的技巧 与 操作
    34                     if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
    35                         Class<?>[] parameterTypes = method.getParameterTypes();
    36                         //如果参数只有一个
    37                         if (parameterTypes.length == 1) {
    38                             String modifierString = methodName.substring(ON_EVENT_METHOD_NAME.length());
    39                             //取ThreadMode
    40                             ThreadMode threadMode;
    41                             if (modifierString.length() == 0) {
    42                                 threadMode = ThreadMode.PostThread;
    43                             } else if (modifierString.equals("MainThread")) {
    44                                 threadMode = ThreadMode.MainThread;
    45                             } else if (modifierString.equals("BackgroundThread")) {
    46                                 threadMode = ThreadMode.BackgroundThread;
    47                             } else if (modifierString.equals("Async")) {
    48                                 threadMode = ThreadMode.Async;
    49                             } else {
    50                                 if (skipMethodVerificationForClasses.containsKey(clazz)) {
    51                                     continue;
    52                                 } else {
    53                                     throw new EventBusException("Illegal onEvent method, check for typos: " + method);
    54                                 }
    55                             }
    56                             Class<?> eventType = parameterTypes[0];
    57                             methodKeyBuilder.setLength(0);
    58                             methodKeyBuilder.append(methodName);
    59                             methodKeyBuilder.append('>').append(eventType.getName());
    60                             //onEventMainThread>java.lang.String
    61                             //methodKey就是上面的形式,可以看出来是方法名>参数  的格式
    62                             String methodKey = methodKeyBuilder.toString();
    64                             //这个地方先去这个hashset里面add这个key,当然了,如果你这个hashset里面已经有这个key
    65                             //那必然是add不成功的,只有add成功返回true以后括号内的代码才会得到执行
    66                             if (eventTypesFound.add(methodKey)) {
    67                                 // Only add if not already found in a sub class
    68                                 //这个地方就是构造SubscriberMethod对象放到list里 准备返回
    69                                 subscriberMethods.add(new SubscriberMethod(method, threadMode, eventType));
    70                             }
    71                         }
    72                     } else if (!skipMethodVerificationForClasses.containsKey(clazz)) {
    73                         Log.d(EventBus.TAG, "Skipping method (not public, static or abstract): " + clazz + "."
    74                                 + methodName);
    75                     }
    76                 }
    77             }
    78             //这里注意还在大的while循环内,所以你传进去的类自己查完一遍方法以后 还会去找他的父类继续查询方法
    79             //一直遍历到父类为 那些java android开头的基类为止!
    80             clazz = clazz.getSuperclass();
    81 
    82         }
    83         if (subscriberMethods.isEmpty()) {
    84             throw new EventBusException("Subscriber " + subscriberClass + " has no public methods called "
    85                     + ON_EVENT_METHOD_NAME);
    86         } else {
    87             synchronized (methodCache) {
    88                 methodCache.put(key, subscriberMethods);
    89             }
    90             return subscriberMethods;
    91         }
    92     }

    然后我们来看看register函数里面 5-6行 那个循环遍历做了什么

    首先我们看看这个循环调用的方法:

     1 /**
     2      * @param subscriber       方法所述的类的 包名+类名
     3      * @param subscriberMethod
     4      * @param sticky
     5      * @param priority
     6      */
     7     private void subscribe(Object subscriber, SubscriberMethod subscriberMethod, boolean sticky, int priority) {
     8         //这个eventtype就是方法的参数的类名
     9         Class<?> eventType = subscriberMethod.eventType;
    10  
    11         CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    12         Subscription newSubscription = new Subscription(subscriber, subscriberMethod, priority);
    13         if (subscriptions == null) {
    14             subscriptions = new CopyOnWriteArrayList<Subscription>();
    15             subscriptionsByEventType.put(eventType, subscriptions);
    16         } else {
    17             if (subscriptions.contains(newSubscription)) {
    18                 throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
    19                         + eventType);
    20             }
    21         }
    22 
    23         // Starting with EventBus 2.2 we enforced methods to be public (might change with annotations again)
    24         // subscriberMethod.method.setAccessible(true);
    25         //这个就是优先级高的位置在前面
    26         int size = subscriptions.size();
    27         for (int i = 0; i <= size; i++) {
    28             if (i == size || newSubscription.priority > subscriptions.get(i).priority) {
    29                 subscriptions.add(i, newSubscription);
    30                 break;
    31             }
    32         }
    33 
    34         List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    35         if (subscribedEvents == null) {
    36             subscribedEvents = new ArrayList<Class<?>>();
    37             typesBySubscriber.put(subscriber, subscribedEvents);
    38         }
    39         subscribedEvents.add(eventType);
    40 
    41         if (sticky) {
    42         
    43             if (eventInheritance) {
    44                 // Existing sticky events of all subclasses of eventType have to be considered.
    45                 // Note: Iterating over all events may be inefficient with lots of sticky events,
    46                 // thus data structure should be changed to allow a more efficient lookup
    47                 // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
    48                 Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
    49                 for (Map.Entry<Class<?>, Object> entry : entries) {
    50                     Class<?> candidateEventType = entry.getKey();
    51                     if (eventType.isAssignableFrom(candidateEventType)) {
    52                         Object stickyEvent = entry.getValue();
    53                         checkPostStickyEventToSubscription(newSubscription, stickyEvent);
    54                     }
    55                 }
    56             } else {
    57                 Object stickyEvent = stickyEvents.get(eventType);
    58                 checkPostStickyEventToSubscription(newSubscription, stickyEvent);
    59             }
    60         }
    61     }

    10-13行 我们可以看出来 这个函数 主要是为了构造subscription这个list对象。

      /**
         * 这个map 存储方法的地方 key就是eventType,value就是copyOnWriteArrayList value就是方法的一切
         */
        private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;

    我们可以看看这个类是什么

     1 /**
     2  * 这个类里面包含有SubscriberMethod类对象,
     3  * subscriber
     4  */
     5 final class Subscription {
     6     //这个实际上就是描述方法所属的类的
     7     final Object subscriber;
     8     //描述方法的类
     9     final SubscriberMethod subscriberMethod;
    10     //优先级
    11     final int priority;
    12     /**
    13      * Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery
    14      * {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions.
    15      */
    16     volatile boolean active;
    17 
    18     Subscription(Object subscriber, SubscriberMethod subscriberMethod, int priority) {
    19         this.subscriber = subscriber;
    20         this.subscriberMethod = subscriberMethod;
    21         this.priority = priority;
    22         active = true;
    23     }
    24 
    25     @Override
    26     public boolean equals(Object other) {
    27         if (other instanceof Subscription) {
    28             Subscription otherSubscription = (Subscription) other;
    29             return subscriber == otherSubscription.subscriber
    30                     && subscriberMethod.equals(otherSubscription.subscriberMethod);
    31         } else {
    32             return false;
    33         }
    34     }
    35 
    36     @Override
    37     public int hashCode() {
    38         return subscriber.hashCode() + subscriberMethod.methodString.hashCode();
    39     }
    40 }

    所以总结起来,SubscriberMethod 就是对方法的描述,而我们的SubscriberMethod 实际上就是Subscription的子集,Subscription除了有描述方法的对象以外,还有这个方法所属的类,

    而我们的register方法总体来说 就是先通过findSubscriberMethods方法 取得我们注册类(就是你register调用的时候传的this)所需要的的那些方法(注意不是每个方法都需要 只选择自己需要的)

    然后把这些方法 做一个list,最后再通过便利这个list : 用每一个SubscriberMethod 对象和这个方法所需的类(包名+类名) 来构造出一个Subscription对象,然后把这个对象

    存储在SubscriptionsByEventType里,注意这个map的key 实际上就是eventType,而value则代表方法的list,换句话说。

    这个SubscriptionsByEventType 是一个键值对,它的key 实际上就是我们的类名,value则是这个类里面我们需要存储的方法的list!

    这就是register的大致流程,我们再来看看post 流程即可。

     1  /**
     2      * Posts the given event to the event bus.
     3      */
     4     public void post(Object event) {
     5         PostingThreadState postingState = currentPostingThreadState.get();
     6         //这个地方可以看出来是每次有人调用post方法的时候 都会从postingState取出这个队列,然后把这个事件放到这个队列里
     7         List<Object> eventQueue = postingState.eventQueue;
     8         eventQueue.add(event);
     9 
    10         //这个判断isPosting 主要是为了保证同一时间只能有一个线程在处理括号体里的内容
    11         //currentPostingThreadState 是用threadlocal来构造的 所以保证了同步性
    12         if (!postingState.isPosting) {
    13             postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
    14             postingState.isPosting = true;
    15             if (postingState.canceled) {
    16                 throw new EventBusException("Internal error. Abort state was not reset");
    17             }
    18             try {
    19                 while (!eventQueue.isEmpty()) {
    20                     //队列不为空就处理
    21                     postSingleEvent(eventQueue.remove(0), postingState);
    22                 }
    23             } finally {
    24                 postingState.isPosting = false;
    25                 postingState.isMainThread = false;
    26             }
    27         }
    28     }

    先看看第5行的postingState是什么

     1  /**
     2      * 静态类,里面除了有一个队列以外,还有几个标志位,以及一个Subscription
     3      */
     4     final static class PostingThreadState {
     5         final List<Object> eventQueue = new ArrayList<Object>();
     6         boolean isPosting;
     7         boolean isMainThread;
     8         Subscription subscription;
     9         Object event;
    10         boolean canceled;
    11     }

    这个地方就能看出来,我们每次调用post 都是往eventQueue里面添加一个事件,而12行开始则是从队列里面

    取事件来处理,注意12行开始 一次性只能允许一个线程使用~同步的

    然后继续看是怎么处理的。

     1  /**
     2      * @param event        方法的参数的类名
     3      * @param postingState
     4      * @throws Error
     5      */
     6     private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
     7       
     8         Class<?> eventClass = event.getClass();
     9         boolean subscriptionFound = false;
    10        
    11         if (eventInheritance) {
    12             List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
    13             int countTypes = eventTypes.size();
    14             for (int h = 0; h < countTypes; h++) {
    15                 Class<?> clazz = eventTypes.get(h);
    16                 //这个地方就是取出Subscription对象的的所有信息!发消息也是在这个函数里发送的
    17                 subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
    18             }
    19         } else {
    20             subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
    21         }
    22         if (!subscriptionFound) {
    23             if (logNoSubscriberMessages) {
    24                 Log.d(TAG, "No subscribers registered for event " + eventClass);
    25             }
    26             if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
    27                     eventClass != SubscriberExceptionEvent.class) {
    28                 post(new NoSubscriberEvent(this, event));
    29             }
    30         }
    31     }

    继续跟进去

     1 private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
     2         CopyOnWriteArrayList<Subscription> subscriptions;
     3         synchronized (this) {
     4             subscriptions = subscriptionsByEventType.get(eventClass);
     5         }
     6         if (subscriptions != null && !subscriptions.isEmpty()) {
     7             for (Subscription subscription : subscriptions) {
     8                 postingState.event = event;
     9                 postingState.subscription = subscription;
    10                 boolean aborted = false;
    11                 try {
    12                     //这个地方就是真正发消息的地方了
    13                     postToSubscription(subscription, event, postingState.isMainThread);
    14                     aborted = postingState.canceled;
    15                 } finally {
    16                     postingState.event = null;
    17                     postingState.subscription = null;
    18                     postingState.canceled = false;
    19                 }
    20                 if (aborted) {
    21                     break;
    22                 }
    23             }
    24             return true;
    25         }
    26         return false;
    27     }

    可以看出来 2-6行 就是从我们register流程里存储的键值对里 把我们存放的方法给取出来。,

    取出来以后 就可以反射调用他们的方法了

     1   /**
     2      * 这个类就是反射执行方法 并且是最终执行回调方法的地方
     3      *
     4      * @param subscription
     5      * @param event
     6      * @param isMainThread
     7      */
     8     private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
     9         switch (subscription.subscriberMethod.threadMode) {
    10             case PostThread:
    11                 invokeSubscriber(subscription, event);
    12                 break;
    13             case MainThread:
    14                 if (isMainThread) {
    15                     invokeSubscriber(subscription, event);
    16                 } else {
    17                     mainThreadPoster.enqueue(subscription, event);
    18                 }
    19                 break;
    20             case BackgroundThread:
    21                 if (isMainThread) {
    22                     backgroundPoster.enqueue(subscription, event);
    23                 } else {
    24                     invokeSubscriber(subscription, event);
    25                 }
    26                 break;
    27             case Async:
    28                 asyncPoster.enqueue(subscription, event);
    29                 break;
    30             default:
    31                 throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
    32         }
    33     }

    13-18行 这个case 如果是主线程,那么就直接反射方法,如果不是的话 则要放到主线程handler里执行。

    1  private final HandlerPoster mainThreadPoster;
    1  //这个就是主线程handler初始化
    2         mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
     1 /*
     2  * Copyright (C) 2012 Markus Junginger, greenrobot (http://greenrobot.de)
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *      http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15  */
    16 package de.greenrobot.event;
    17 
    18 import android.os.Handler;
    19 import android.os.Looper;
    20 import android.os.Message;
    21 import android.os.SystemClock;
    22 
    23 final class HandlerPoster extends Handler {
    24 
    25     private final PendingPostQueue queue;
    26     private final int maxMillisInsideHandleMessage;
    27     private final EventBus eventBus;
    28     private boolean handlerActive;
    29 
    30     HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
    31         super(looper);
    32         this.eventBus = eventBus;
    33         this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
    34         queue = new PendingPostQueue();
    35     }
    36 
    37     void enqueue(Subscription subscription, Object event) {
    38         PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
    39         synchronized (this) {
    40             queue.enqueue(pendingPost);
    41             if (!handlerActive) {
    42                 handlerActive = true;
    43                 if (!sendMessage(obtainMessage())) {
    44                     throw new EventBusException("Could not send handler message");
    45                 }
    46             }
    47         }
    48     }
    49 
    50     @Override
    51     public void handleMessage(Message msg) {
    52         boolean rescheduled = false;
    53         try {
    54             long started = SystemClock.uptimeMillis();
    55             while (true) {
    56                 PendingPost pendingPost = queue.poll();
    57                 if (pendingPost == null) {
    58                     synchronized (this) {
    59                         // Check again, this time in synchronized
    60                         pendingPost = queue.poll();
    61                         if (pendingPost == null) {
    62                             handlerActive = false;
    63                             return;
    64                         }
    65                     }
    66                 }
    67                 eventBus.invokeSubscriber(pendingPost);
    68                 long timeInMethod = SystemClock.uptimeMillis() - started;
    69                 if (timeInMethod >= maxMillisInsideHandleMessage) {
    70                     if (!sendMessage(obtainMessage())) {
    71                         throw new EventBusException("Could not send handler message");
    72                     }
    73                     rescheduled = true;
    74                     return;
    75                 }
    76             }
    77         } finally {
    78             handlerActive = rescheduled;
    79         }
    80     }
    81 }

    51-77行 就是我们实际最终调用的地方。

    同样的 我们在看看20-26行的这个background这个case

     1 final class BackgroundPoster implements Runnable {
     2 
     3     private final PendingPostQueue queue;
     4     private final EventBus eventBus;
     5 
     6     private volatile boolean executorRunning;
     7 
     8     BackgroundPoster(EventBus eventBus) {
     9         this.eventBus = eventBus;
    10         queue = new PendingPostQueue();
    11     }
    12 
    13     public void enqueue(Subscription subscription, Object event) {
    14         PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
    15         synchronized (this) {
    16             queue.enqueue(pendingPost);
    17             if (!executorRunning) {
    18                 executorRunning = true;
    19                 eventBus.getExecutorService().execute(this);
    20             }
    21         }
    22     }
    23 
    24     @Override
    25     public void run() {
    26         try {
    27             try {
    28                 while (true) {
    29                     PendingPost pendingPost = queue.poll(1000);
    30                     if (pendingPost == null) {
    31                         synchronized (this) {
    32                             // Check again, this time in synchronized
    33                             pendingPost = queue.poll();
    34                             if (pendingPost == null) {
    35                                 executorRunning = false;
    36                                 return;
    37                             }
    38                         }
    39                     }
    40                     eventBus.invokeSubscriber(pendingPost);
    41                 }
    42             } catch (InterruptedException e) {
    43                 Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);
    44             }
    45         } finally {
    46             executorRunning = false;
    47         }
    48     }

    一看就知道 他是runnable对象 必然是在后台 在子线程内执行,同时他也是一次性只能做一次操作,完成一个事件,

    最后我们来看看Async这个case:

     1 /*
     2  * Copyright (C) 2012 Markus Junginger, greenrobot (http://greenrobot.de)
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *      http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15  */
    16 package de.greenrobot.event;
    17 
    18 
    19 /**
    20  * Posts events in background.
    21  * 
    22  * @author Markus  并发执行任务,在线程池内执行
    23  */
    24 class AsyncPoster implements Runnable {
    25 
    26     private final PendingPostQueue queue;
    27     private final EventBus eventBus;
    28 
    29     AsyncPoster(EventBus eventBus) {
    30         this.eventBus = eventBus;
    31         queue = new PendingPostQueue();
    32     }
    33 
    34     public void enqueue(Subscription subscription, Object event) {
    35         PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
    36         queue.enqueue(pendingPost);
    37         eventBus.getExecutorService().execute(this);
    38     }
    39 
    40     @Override
    41     public void run() {
    42         PendingPost pendingPost = queue.poll();
    43         if(pendingPost == null) {
    44             throw new IllegalStateException("No pending post available");
    45         }
    46         eventBus.invokeSubscriber(pendingPost);
    47     }
    48 
    49 }

    这个地方和background相同的就是也是在非主线程,在子线程内执行,但是这个地方是在线程池内执行,可以并发执行多个任务,

    而我们的background 则一次性只能执行一个任务,这是2者之间的区别。

  • 相关阅读:
    Repeater控件用法
    python的文件锁使用
    python的文件锁使用
    python的文件锁使用
    linux下文件描述符的介绍
    linux下文件描述符的介绍
    linux下文件描述符的介绍
    Linux 2.6 中的文件锁
    Linux 2.6 中的文件锁
    Linux 2.6 中的文件锁
  • 原文地址:https://www.cnblogs.com/punkisnotdead/p/4794151.html
Copyright © 2011-2022 走看看