EventBus

事件总线:为了简化组件之间以及组件和后台线程之间的通信,在保证其高效性的同时降低耦合度。比如ActivityFragmentThreadService等组件的通信。

EventBus简介

EventBus是一款针对Andriod优化的发布-订阅事件总线。其优点是开销小,代码优雅,以及降低发送者和接收者之间的耦合性。

组件之间的交互也可以用广播来处理,但是使用广播比较麻烦,效率效率不高。如果传递的数据是实体类,需要序列化,传递成本有点高。

EventBus的三要素

EventBus工作原理

publisher [ˈpʌblɪʃər] 出版者,出版商;发行人 subscriber [səbˈskraɪbər] 订户;签署者;捐献者

  • Event:事件,可以是任意类型的对象。
  • Subscriber:事件订阅者。EventBus 3.0之前消息处理的方式只能限定于onEventonEventMainThreadonEventBackgroundonEventAsync,它们分别代表4种线程模型。而在EventBus 3.0之后,事件处理的方式可以随便起名,但是只需要添加一个注解@Subscribe,并且要指定线程模型(默认为POSTING
  • **Publisher:事件发布者,可以在任意线程的任意位置发送事件。**直接调用EventBus.post(Object)方法,根据参数类型,会自动调用订阅相应类型事件的函数
@Subscribe注解

subscribe [səbˈskraɪb] 订阅;捐款;认购;赞成;签署

sticky [ˈstɪki] 粘的;粘性的

priority [praɪˈɔːrəti] n. 优先;优先权;[数] 优先次序;优先考

以下是@Subscribe的源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
	// 线程模式,即在哪个线程处理事件,默认为POSITION
  ThreadMode threadMode() default ThreadMode.POSTING;
	// 是否支持黏性事件,默认为false
  boolean sticky() default false;
	// 优先级,默认为0,先处理优先级高的事件
  int priority() default 0;
}
EventBus4种线程模型(ThreadMode
  • ThreadMode.POSTING:默认线程模型,事件在哪个线程中发布就在哪个线程中处理。 避免了线程切换,效率高。
  • ThreadMode.MAIN:不管事件在哪个线程中发布,都会在UI线程中处理。如果发布线程是主线程,将阻塞post调用,如果是子线程,事件在队列中排队等待处理,是非阻塞的。
  • Thread.MAIN_ORDERED:不管事件在哪个线程中发布,都会在UI线程中处理。不同于ThreadMode.MAIN,事件始终排队等待处理,这就确保了post调用是非阻塞的。
  • ThreadMode.BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件的处理函数会在新的线程中运行;如果事件是从子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。
  • ThreadMode.ASYNC:无论事件在哪个线程中发布,该事件处理函数都会在新的子线程中执行。

阻塞:调用结果返回之前,线程会被挂起。非阻塞:在没有得到结果之前,不会阻塞当前线程

EventBus基本用法

EventBus使用起来分为5个步骤:

  1. 自定义一个事件类:
  public class MessageEvent { 
  }
  1. 在需要订阅事件的地方注册事件,一般在onStart方法中注册订阅事件:
  @Override
  protected void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
  }
  1. 发送事件:
Event.getDefault().post(messageEvent);
  1. 处理事件:消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且需要执行线程模型(默认为POSTING
   @Subscribe (threadMode = ThreadMode.MAIN)
   public void XXX (MessageEvent messageEvent) {
     
   }
  1. 取消事件订阅,一般在onStop事件中取消订阅事件:
   @Override
   protected void onStop() {
     super.onStop();
     EventBus.getDefault().unregister(this);
   }
EventBus应用举例
1. 添加依赖库,配置gradle
implementation 'org.greenrobot:eventbus:3.2.0'
2. 定义消息事件类
public class MessageEvent {

  private String message;

  public MessageEvent(String message) {
    this.message = message;
  }

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }
}
3. 注册和取消订阅事件

MainActivity中注册和取消订阅事件:

public class TestActivity extends AppCompatActivity {

  private TextView tv_message;
  private Button btn_message;
  private Button btn_subscribe;

  @Override
  protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tv_message = findViewById(R.id.tv_message);
    btn_message = findViewById(R.id.btn_message);
    btn_subscribe = findViewById(R.id.btn_subscribe);

    tv_message.setText("MainActivity");
    btn_message.setOnClickListener(v -> startActivity(new Intent(TestActivity.this, SecondActivity.class)));

    btn_subscribe.setOnClickListener(v -> EventBus.getDefault().register(TestActivity.this));
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
  }
}
4. 事件订阅者处理事件

TestActivity中定义方法来处理事件,ThreadMode设置为MAIN,事件的处理会在UI线程中执行,用TextView来展示收到的事件消息:

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMoonEvent(MessageEvent messageEvent) {
  tv_message.setText(messageEvent.getMessage());
}
5. 事件发布者发布事件

创建SecondActivity来发布消息:

public class SecondActivity extends AppCompatActivity {

  private Button btn_message;
  private TextView tv_message;

  @Override
  protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);

    tv_message = findViewById(R.id.tv_message);
    btn_message = findViewById(R.id.btn_message);

    tv_message.setText("SecondActivity");
    btn_message.setOnClickListener(v -> {
      EventBus.getDefault().post(new MessageEvent("Welcome to EventBus"));
      finish();
    });
  }
}

点击MainActivity中的“注册事件”按钮来注册事件,然后点击“跳转到SECONDACTIVITY”按钮,跳转到SecondActivity中,接下来点击“发送事件”这个按钮。

6. ProGuard混淆规则
-keepattributes *Annotation*
-keepclassmembers class * {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
 
# And if you use AsyncExecutor:
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

EventBus黏性事件

黏性事件:就是在发送事件之后再订阅该事件也能接收到,和黏性广播类似。

1. 订阅者处理黏性事件

MainActivity中重新写一个方法来处理黏性事件:

@Subscribe(threadMode = ThreadMode.POSTING, sticky = true)
public void onMoonEvent(MessageEvent messageEvent) {
  tv_message.setText(messageEvent.getMessage());
}
2. 发送黏性事件

SecondActivity中定义一个Button来发送黏性事件:

btn_message.setOnClickListener(v -> {
  EventBus.getDefault().postSticky(new MessageEvent("黏性事件"));
  finish();
});

MainActivity中,不用点击"注册事件"按钮,而是直接跳转到SecondActivity中点击“发送黏性事件”。这时界面回到MainActivity中,TextView仍旧显示MainActivity的字段,这是因为还没有订阅事件,就点击“注册事件”按钮,TextView内容发生改变,显示“黏性事件”,说明事件被成功接收到了。

3. 取消注册
@Override
protected void onDestroy() {
  super.onDestroy();
  // 移除黏性事件
  EventBus.getDefault().removeAllStickyEvents();
  EventBus.getDefault().unregister(this);
}

源码解析EventBus

1. EventBus的构造方法

volatile [ˈvɑːlətl] 不稳定的;反复无常的 synchronized [ˈsɪŋkrənaɪzd] 同步的;同步化的

在使用EventBus的时候,首先会调用EventBus.getDefault()来获取EventBus的实例:

public class EventBus {
  static volatile EventBus defaultInstance;

  public static EventBus getDefault() {
    EventBus instance = defaultInstance;
    if (instance == null) {
      synchronized (EventBus.class) {
        instance = EventBus.defaultInstance;
        if (instance == null) {
          instance = EventBus.defaultInstance = new EventBus();
        }
      }
    }
    return instance;
  }
}

**这是一个单例模式,采用了双重检查模式(Double check the lock DCL)。**以下是EventBus的构造方法:

public class EventBus {
  
  private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
  
  public EventBus() {
    this(DEFAULT_BUILDER);
  }

  EventBus(EventBusBuilder builder) {
    logger = builder.getLogger();
    subscriptionsByEventType = new HashMap<>();
    typesBySubscriber = new HashMap<>();
    stickyEvents = new ConcurrentHashMap<>();
    mainThreadSupport = builder.getMainThreadSupport();
    mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
    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;
  }
}

通过构造一个EventBusBuilder来对EventBus进行配置,这里采用了建造者模式。

2. 订阅者注册

获取EventBus后,可以将订阅者注册到EventBus中:

public class EventBus {
  
  private final SubscriberMethodFinder subscriberMethodFinder;
  
  public void register(Object subscriber) {
    Class<?> subscriberClass = subscriber.getClass(); 
    // 1.查找一个SubscriberMethod的集合,也就是传进来的订阅者的所有订阅方法
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    synchronized (this) {
      // 2. 遍历订阅者的所有订阅方法来完成订阅者的注册操作
      for (SubscriberMethod subscriberMethod : subscriberMethods) {
        subscribe(subscriber, subscriberMethod);
      }
    }
  }
  
}

// SubscriberMethod封装了Mehtod对象、线程模式、事件类型、优先级、是否是黏性事件等
public class SubscriberMethod {
    final Method method;
    final ThreadMode threadMode;
    final Class<?> eventType;
    final int priority;
    final boolean sticky;
    String methodString;
}

register方法中做了两件事:一是查找订阅者的订阅方法,另一件事是遍历订阅者的订阅方法来完成注册。

1. 查找订阅者的订阅方法

以下是SubscriberMehodFinder.findSubscriberMethods方法:

class SubscriberMethodFinder {
  
  private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
  
  List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
    // 1. 从缓存中查找是否有订阅方法的集合,如果找到了就立即返回
    List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
    if (subscriberMethods != null) {
      return subscriberMethods;
    }

    // 2. 如果缓存中没有,则根据ignoreGeneratedIndex属性来选择采用何种方法来查找订阅方法的集合,ignoreGeneratedIndex属性表示是否忽略注解器生成的MyEventBusIndex,如何生成MyEventBusIndex类以及它的使用,默认值是false,可以通过EventBusBuilder来设置它的值。
    if (ignoreGeneratedIndex) {
      subscriberMethods = findUsingReflection(subscriberClass);
    } else {
      // 3. 通过EventBus单例模式来获取默认的EventBus对象,也就是ignoreGeneratedIndex=false的情况
      subscriberMethods = findUsingInfo(subscriberClass);
    }
    if (subscriberMethods.isEmpty()) {
      
    } else {
      // 4. 找到订阅方法的集合后,放入缓存,以免下次继续查找
      METHOD_CACHE.put(subscriberClass, subscriberMethods);
      return subscriberMethods;
    }
  }
  
  // 3.1 获取订阅者信息
  private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
    FindState findState = prepareFindState();
    findState.initForSubscriber(subscriberClass);
    while (findState.clazz != null) {
      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 {
        // 3.2 通过反射来查找订阅事件
        findUsingReflectionInSingleClass(findState);
      }
      findState.moveToSuperclass();
    }
    return getMethodsAndRelease(findState);
  }
}
2. 订阅者的注册过程

以下是EventBus.subscribe方法:

public class EventBus {
  
  private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
  private final Map<Object, List<Class<?>>> typesBySubscriber;
  
  private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    // 1. 得到当前订阅了事件的方法的参数类型
    Class<?> eventType = subscriberMethod.eventType;
    // 2. 会根据subscriber(订阅者)和subscribeMethod(订阅方法)创建一个Subscription(订阅对象)
    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
    // 3. 根据eventType(事件类型)获取Subscription(订阅对象集合)
    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    // 4. 创建subscriptions对象,并将subscriptions根据EventType保存在subscriptionsByEventType(Map集合)
    if (subscriptions == null) {
      subscriptions = new CopyOnWriteArrayList<>();
      subscriptionsByEventType.put(eventType, subscriptions);
    } else {
      
    }

    int size = subscriptions.size();
    for (int i = 0; i <= size; i++) {
      if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
        // 5. 按照订阅方法的优先级插入到订阅对象集合中,完成订阅方法的注册
        subscriptions.add(i, newSubscription);
        break;
      }
    }

    // 6. 通过subscriber获取subscribeEvents(事件类型集合)
    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    if (subscribedEvents == null) {
      // 7. 创建subscribedEvents,根据subscriber添加到typesBySubscriber(Map集合),
      subscribedEvents = new ArrayList<>();
      typesBySubscriber.put(subscriber, subscribedEvents);
    }
    subscribedEvents.add(eventType);

    // 8. 如果是黏性事件,则从stickyEvents事件保存队列中取出该事件类型的事件发送给当前订阅者
    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);
      }
    }
  }
}

EventBus.subscribe方法做了两件事:一件是将subscriptions根据eventType封装到subscriptionsByEventTyps中,将subscribedEvent根据subscriber封装到typesBySubscriber中;另一件事对黏性事件的处理。

3. 事件的发送

在获取EventBus对象后,可以通过post方法来对进行对事件的提交,以下是EventBus.post方法的源码:

public class EventBus {
  
  public void post(Object event) {
    // 保存着事件队列和线程状态信息
    PostingThreadState postingState = currentPostingThreadState.get();
    // 1.获取事件队列,并将当前事件插入事件队列
    List<Object> eventQueue = postingState.eventQueue;
    eventQueue.add(event);

    if (!postingState.isPosting) {
      postingState.isMainThread = isMainThread();
      postingState.isPosting = true;
      if (postingState.canceled) {
        throw new EventBusException("Internal error. Abort state was not reset");
      }
      try {
        // 2. 处理队列中的所有事件,并移除该事件
        while (!eventQueue.isEmpty()) {
          postSingleEvent(eventQueue.remove(0), postingState);
        }
      } finally {
        postingState.isPosting = false;
        postingState.isMainThread = false;
      }
    }
  }
  
}

首先从PostingThreadState对象中取出事件队列,然后将当前的事件插入事件队列。最后将队列中的事件依次交由postSingleEvent方法进行处理,并移除该事件。 以下是postSingleEvent方法的源码:

public class EventBus {
  
  private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
    Class<?> eventClass = event.getClass();
    boolean subscriptionFound = false;
    // eventInheritance表示是否向上查找事件的父类,默认为true,可以通过EventBuilder中进行配置。
    if (eventInheritance) {
      // 找到所有父类事件并保存在List中,然后通过postSingleEventForEventType方法对事件逐一处理
      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) {
        logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
      }
      if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
          eventClass != SubscriberExceptionEvent.class) {
        post(new NoSubscriberEvent(this, event));
      }
    }
  }
  
}

eventInheritance表示是否向上查找事件的父类,它的默认值是true,可以通过EventBusBuilder中进行配置。当eventInheritancetrue时,则通过lookupAllEventTypes找到所有父类事件并存在List中,然后通过postSingleEventForEventType方法对事件逐一处理postSingleEventForEventType的源码如下:

public class EventBus {
  
  private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
    CopyOnWriteArrayList<Subscription> subscriptions;
    synchronized (this) {
      // 1
      subscriptions = subscriptionsByEventType.get(eventClass);
    }
    if (subscriptions != null && !subscriptions.isEmpty()) {
      // 2
      for (Subscription subscription : subscriptions) {
        postingState.event = event;
        postingState.subscription = subscription;
        boolean aborted;
        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;
  }

}

注释1处同步取出事件对应的subscriptions(订阅对象集合),注释2处遍历subscriptions,将事件event和对应的subscription(订阅对象)传递给postingState并调用postToSubscription方法对事件进行处理, 以下是postToSubscription方法:

public class EventBus {
  private final Poster mainThreadPoster;

  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将我们订阅事件添加到主线程队列中
          mainThreadPoster.enqueue(subscription, event);
        }
        break;
      case MAIN_ORDERED:
        if (mainThreadPoster != null) {
          mainThreadPoster.enqueue(subscription, event);
        } else {
          // temporary: technically not correct as poster not decoupled from subscriber
          invokeSubscriber(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);
    }
  }
}

取出订阅方法的threadMode(线程模式),之后根据threadMode来分别处理。如果threadModeMAIN,若提交事件的线程是主线程,则通过反射直接运行订阅的方法;若其不是主线程,则需要mainThreadPoster将订阅的事件添加到主线程队列中。

4. 订阅者取消注册

取消注册需要调用EventBus.unregister方法:

public class EventBus {

  public synchronized void unregister(Object subscriber) {
    List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber); // 1. 
    if (subscribedTypes != null) {
      for (Class<?> eventType : subscribedTypes) {
        unsubscribeByEventType(subscriber, eventType); // 2.
      }
      typesBySubscriber.remove(subscriber); // 3. 
    } else {
      
    }
  }
}

typesBySubscriber是一个map集合,注释1出通过subscriber主动到subscribedTypes(事件类型集合)。注释3处将subscriber对应的eventTypetypesBySubscriber中移除。 注释2处遍历subscribedTypes,并调用unsubscribeByEventType方法:

public class EventBus {
  
  private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
    List<Subscription> subscriptions = subscriptionsByEventType.get(eventType); // 1
    if (subscriptions != null) {
      int size = subscriptions.size();
      for (int i = 0; i < size; i++) {
        Subscription subscription = subscriptions.get(i);
        if (subscription.subscriber == subscriber) {
          subscription.active = false;
          subscriptions.remove(i);
          i--;
          size--;
        }
      }
    }
  }
  
}

注释1出通过eventType来得到对应的subscriptions(订阅对象集合),并在for循环中判断如果subscription(订阅对象)的subscriber(订阅者)属性等于传进来的subscriber,则从subscriptions中移除该subscription

5. 黏性事件
注册

EventBus.registersubscribe方法中,有一段代码是用来处理黏性事件的:

public class EventBus {
  
  private final Map<Class<?>, Object> stickyEvents;
  
  private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {

    if (subscriberMethod.sticky) {
      // 1. 默认为true,表示是否向上查找事件的父类
      if (eventInheritance) {
        // 2. 发送黏性事件时,保存了事件类型和对应事件
        Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
        for (Map.Entry<Class<?>, Object> entry : entries) {
          Class<?> candidateEventType = entry.getKey();
          if (eventType.isAssignableFrom(candidateEventType)) {
            // 3. 获取对应的事件
            Object stickyEvent = entry.getValue();
            // 4. 处理黏性事件
            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
          }
        }
      } else {
        Object stickyEvent = stickyEvents.get(eventType);
        checkPostStickyEventToSubscription(newSubscription, stickyEvent);
      }
    }
  }
}

处理黏性事件就是遍历stickyEvents,如果当前要注册的事件订阅方法是黏性的,并且该方法接收的事件类型和stickyEvents中某个事件类型相同或者是其父类,则取出stickyEvent中对应事件类型的具体事件,做进一步处理。

subscribe方法的核心是checkPostStickyEventToSubscription

public class EventBus {
  
  private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
    if (stickyEvent != null) {
      postToSubscription(newSubscription, stickyEvent, isMainThread());
    }
  }
}
发送

EventBus.postSticky源码如下:

public class EventBus {
  
  private final Map<Class<?>, Object> stickyEvents;
  
  public void postSticky(Object event) {
    synchronized (stickyEvents) {
      stickyEvents.put(event.getClass(), event);
    }
    post(event);
  }
}

postSticky()方法主要做了两件事:先将事件类型和对应事件保存到stickyEvents中,方便使用。然后执行post(event)继续发送事件,这个post方法就是之前普通事件的发送方法,所以,如果在发送黏性事件之前,已经有了对应类型事件的订阅者,即使它是非黏性的,也可以接收到发送出的黏性事件。

总结

register
post

unregister

参考

https://github.com/greenrobot/EventBus/

https://segmentfault.com/a/1190000020052249?utm_source=tag-newest

https://zhuanlan.zhihu.com/p/51357583

https://segmentfault.com/a/1190000018706349/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值