Is EventBus a software architecture?
No, not by itself. EventBus may help with certain architectural problems like decoupling of components. You should still think about your app’s architecture. Often, dividing your app into layers (e.g. UI, logic, data retrieval) may help to divide and conquer your app’s complexity. Depending on the developer’s taste, EventBus events may span multiple layers (cross-cutting concerns), or may be strictly divided by layers (which may require some awkward re-posting of events however). And always remember: do not overuse EventBus, you can still call methods! 😉
How is EventBus different to Android’s BroadcastReceiver/Intent system?
Unlike Android’s BroadcastReceiver/Intent system, EventBus uses standard Java classes as events and offers a more convenient API. EventBus is intended for a lot more uses cases where you wouldn’t want to go through the hassle of setting up Intents, preparing Intent extras, implementing broadcast receivers, and extracting Intent extras again. Also, EventBus comes with a much lower overhead.
When I post an event, it is received twice or multiple times. But I have just one subscriber method. What can lead to this?
Check if you have multiple instances of your subscriber class registered at the same time to the EventBus. Typical scenarios include: 1.) forgot a call to unregister, 2) a Fragment attached multiple times to an Activity. To verify, it is often enough to add logs to your methods doing register and unregister: if the number of register calls is higher than the number of unregister calls + 1, you have found evidence that your app does not register correctly.
A java.lang.NoClassDefFoundError is throw when a subscriber class is registered. What can I do?
First a bit of background to help you understand what’s going on here: Some Android versions seem to have a bug with reflection when calling getDeclaredMethods or getMethods. The exception is thrown if the class has methods with a parameter that is unavailable to the API level of the device. For example, the class PersistableBundle was added in API level 21. Along with the new class some new life cycle methods were introduced in the class Activity having PersistableBundle as a parameter, for example onCreate (Bundle savedInstanceState, PersistableBundle persistentState). Now, if you override this method and you try to register this Activity to EventBus on a older device, we have exactly the scenario described to cause to bug. Understanding why this happens will help to resolve the issue easily.
Here are a couple suggestions how to fix the scenario (check in given the order):
- Maybe you overwrote a life cycle method with PersistableBundle just by accident. In that case just change to the method without PersistableBundle, for example onCreate (Bundle savedInstanceState).
- Use EventBus 3 with an subscriber index. This will avoid reflection and thus the problem altogether. As a positive side effect, registering subscribers and thus app startup time will be much faster.
- Remove the offending method from your subscriber class. Either pull out the event handler methods into a new subscriber class, or pull out the offending method into a non-subscriber class.
- If the offending method is public, make it non-public. This works because of some “plan b” logic EventBus applies: EventBus first calls getDeclaredMethods, which will fail. Next, EventBus will try again using the getMethods (“plan b”). The latter will succeed because getMethods only returns public methods. However, keep in mind that is the least efficient way in terms of performance (2 reflection calls instead of 1 with getMethods considering the entire class hierarchy).
Why am I getting the warning “The following options were not recognized by any processor: ‘[eventBusIndex]'”?
This happens when you set up the build script, and you did not add any annotations to your code yet. Without any @Subscribe annotations, annotation processor for indexing will not be triggered to consume the ‘eventBusIndex’ option. So, just add some @Subscribe annotations and you should be fine.