Understanding and Using EventBus 3 in Android: Setup, Core Architecture, Index Acceleration, and Best Practices
EventBus 3 provides a lightweight publish/subscribe framework for Android that simplifies inter‑module communication by allowing any object to be posted and received via @Subscribe methods, with optional index acceleration for faster registration, customizable thread modes, and guidance on setup, ProGuard rules, pitfalls, and alternatives.
EventBus is a popular observer‑pattern based publish/subscribe framework for Android. It enables lightweight communication between modules without the need for explicit interfaces, reducing tight coupling and boilerplate.
1. Getting Started – Adding EventBus
In the app module’s build.gradle add the core library:
compile 'org.greenrobot:eventbus:3.0.0'If you want to use the index acceleration feature, you must also add the android-apt plugin and the annotation processor:
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'Apply the plugin and configure the generated index:
apply plugin: 'com.neenbedankt.android-apt'
apt {
arguments {
eventBusIndex "com.study.sangerzhong.studyapp.MyEventBusIndex"
}
}Finally, add the processor dependency:
apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'If the eventBusIndex argument is missing, compilation will fail with No option eventBusIndex passed to annotation processor .
2. Initializing EventBus
EventBus provides a default singleton via EventBus.getDefault() . To use a custom instance with an index:
EventBus mEventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();To replace the default singleton with the custom configuration:
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();3. Defining and Posting Events
Any Object can be an event. A typical event class:
public class DriverEvent { public String info; }Register a subscriber (usually in onStart or onCreate ) and unregister in the corresponding lifecycle method:
mEventBus.register(this);
// ...
mEventBus.unregister(this);Subscribe to an event with the @Subscribe annotation. Example:
@Subscribe(threadMode = ThreadMode.POSTING, priority = 0, sticky = true)
public void handleEvent(DriverEvent event) {
Log.d(TAG, event.info);
}Post an event (or a sticky event) with:
mEventBus.post(new DriverEvent("magnet:?xt=urn:btih……"));4. Core Architecture
EventBus maintains two main maps:
subscriptionByEventType : key = event class, value = list of Subscription (subscriber + callback).
typesBySubscriber : key = subscriber instance, value = set of event types it listens to (used for fast unregistration).
Each callback is represented by a SubscriptionMethod that stores thread mode, priority, sticky flag, etc. The SubscriberMethodFinder builds these objects either by reflection or by reading a generated index.
Four Poster implementations dispatch callbacks on the appropriate thread:
POSTING – same thread as post() .
MAIN – UI thread (uses mainThreadPoster if needed).
BACKGROUND – background thread (uses backgroundPoster if needed).
ASYNC – thread‑pool execution via asyncPoster .
5. Index Acceleration
When EventBus.builder().addIndex(...) is used, the index class implements SubscriberInfoIndex and returns a SubscriberInfo for each subscriber class. The generated class (e.g., MyEventBusIndex ) hard‑codes all @Subscribe methods:
public class MyEventBusIndex implements SubscriberInfoIndex {
private static final Map
, SubscriberInfo> SUBSCRIBER_INDEX;
static {
SUBSCRIBER_INDEX = new HashMap<>();
putIndex(new SimpleSubscriberInfo(com.study.sangerzhong.studyapp.ui.MainActivity.class, true,
new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEvent", com.study.sangerzhong.studyapp.ui.MainActivity.DriverEvent.class,
ThreadMode.POSTING, 0, false)
}));
}
// ... getSubscriberInfo implementation ...
}During registration, SubscriberMethodFinder.findSubscriberMethods() first checks the index via findUsingInfo() . If the index is missing, it falls back to reflection. Using the index reduces registration time from ~10 ms to ~3 ms on a Nexus 6.
6. Common Pitfalls
6.1 ProGuard / R8 Rules
When using the index, keep the generated index class and all methods annotated with @Subscribe :
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe
;
}If you only use annotation‑based lookup (no index), keeping the ThreadMode enum is sufficient:
-keep public enum org.greenrobot.eventbus.ThreadMode { public static *; }6.2 Cross‑process Limitations
EventBus works only across threads within the same process. For inter‑process communication you need a separate IPC mechanism (e.g., Broadcasts) or maintain two independent EventBus instances.
6.3 Event Loops
Bidirectional listeners can create infinite loops. Isolate complex callbacks into dedicated modules or add guard flags to break the cycle.
7. Alternatives
RxJava (or a custom RxBus) can provide similar event‑bus capabilities with richer operators, but it introduces a larger learning curve and additional dependencies. For many projects, EventBus remains the simplest, low‑overhead solution.
Tencent Music Tech Team
Public account of Tencent Music's development team, focusing on technology sharing and communication.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.