Introduction
Otto is a great Android event bus solution developed by SquareUp guys. These guys extract the event bus related classes from Google’s Guava, and optimized it for Android. Event Bus is a great solution to keep your code away from messy anonymous or internal classes only used for event handling! And Otto’s simplicity and performance makes it used to be the most popular event bus solution in Android development.
Android Annotations, as known as AA
, is another great library that makes Android developers’ lives a lot easier. Just annotating the code, AA helps developer handles the most boring or error-proning tasks for you, including binding widgets binding, asynchronous tasks, life time management, etc…
Issue
Otto and AA are the libraries focusing on different aspects. Theoretically speaking, there shouldn’t be any compatibility issue between them. But the reality Otto event is never delivered to AA annotated classes. By inspecting the code with step by step debugging, I found the root cause of the issue is Otto failed to located @Produce
and @Subscribe
annotated methods in AA generated code.
Analysis
After a few study work, I finally understood what is the reason behind:
For performance consideration, Android Annotations actually does it work during the compilation time instead of Runtime. AA will derive the annotated classes, and generate some code according to the annotations applied. During the runtime, the classes got instantiated is actually the derived classes instead of the original one, although in the code is accessed via the original class as interface.
Here is a simple example:
I have the class ServerListAdapter
, which is used to provide data for a grid view.
|
|
And this is the derived class generated by AA
during the compiling-time:
And here is how it is consumed:
As you can see, in the ServerListFragment
, the ServerListAdapter
instance injected into bean
is actually the instance of ServerListAdapter_
. And due to polymorphic, the instance just behaves like a ServerListAdapter
instance.
On the other hand, according to the description on Otto’s Home Page:
In order to receive events, a class instance needs to register with the bus.
…
Registering will only find methods on the immediate class type. Unlike the Guava event bus, Otto will not traverse the class hierarchy and add methods from base classes or interfaces that are annotated. This is an explicit design decision to improve performance of the library as well as keep your code simple and unambiguous.
Otto only search annotations in direct class, which is ServerListAdapter_
in instance, and there isn’t any annotation included. As a consequence, all the @Subscribe
annotated methods are ignored by com.squareup.otto.AnnotatedHandlerFinder
. So the posted events become dead event
due to no subscriber found.
Comments
There is rumor that this issue will be fixed in Otto 2.0
. But according to the comment from Jake Wharton, Otto’s developer, Otto 2.0
will take forever to release.
In fact Otto 2.0 Repo has been not touched for 2 years already. Although we could check out the code and build Otto 2.0 by ourselves, but it takes efforts. Especially when some bug is found.
Conclusion
Luckily, although Otto
turns into “maintenance mode”, the compatibility issue takes forever to resolve. I found a great Otto alternative, EventBus from GreenRobot. A boring name, but great library.
According to EventBus
‘s document, it provides richer feature and better performance than Otto
.
The most important EventBus
is friendly to AndroidAnnoations
. They two works well together.
EventBus and Otto Feature Comparison
EventBus | Otto | |
---|---|---|
Declare event handling methods | Name conventions | Annotations |
Event inheritance | Yes | Yes |
Subscriber inheritance | Yes | No |
Cache most recent events | Yes, sticky events | No |
Event producers (e.g. for coding cached events) | No | Yes |
Event delivery in posting thread | Yes (Default) | Yes |
Event delivery in main thread | Yes | No |
Event delivery in background thread | Yes | No |
Asynchronous event delivery | Yes | No |
EventBus and Otto Performance Comparison
EventBus over Otto | |
---|---|
Posting 1000 events, Android 2.3 emulator | ~70% faster |
Posting 1000 events, S3 Android 4.0 | ~110% faster |
Register 1000 subscribers, Android 2.3 emulator | ~10% faster |
Register 1000 subscribers, S3 Android 4.0 | ~70% faster |
Register subscribers cold start, Android 2.3 emulator | ~350% faster |
Register subscribers cold start, S3 Android 4.0 | About the same |