EventBus is an Android optimized publish/subscribe event bus. A typical use case for Android apps is gluing Activities, Fragments, and background threads together.
5. Status Quo in Android
Activity
Activity
Service / Helper
Fragment Fragment Thread
6. Communication Issues?!
Tight coupling of components
Inflexible, changes are expensive
Boiler plate code
– Define interfaces
– Callbacks for asynch. communication
– Listener management
– Propagation through all layers
7. EventBus Communication
Activity Activity
Event
Bus
Service / Helper
Fragment Fragment Thread
8. EventBus for Android
Event-based Publish/Subscribe
Bus: central communication
Inspired by Guava„s EventBus (Google)
Android-optimized
Open Source, Apache 2 License
https://github.com/greenrobot/EventBus
9. EventBus in 4 Steps
1. Define an event
2. Register subscriber
3. Post an event
4. Receive the event
10. EventBus in 4 Steps: Code!
1. Define an event
public class MyEvent {}
2. Register subscriber
EventBus.getDefault().register(this);
3. Post an event
EventBus.getDefault().post(event);
4. Receive the event
public void onEvent(MyEvent event);
12. EventBus Instances
EventBus instances
Instances are indepent from each other
For many apps, a single instance is fine
„Convenience“ Instance
EventBus.getDefault()
Aquire it anywhere(!) in your code
13. Event Handler Method:
onEvent
EventBus scans subscribers
– During (first) registration of subscriber
– For event handler methods
Event handler methods
– Naming convention: onEvent
– public visibility
– No return value (void)
– Single parameter for the event to receive
14. Type-based Event Routing
Event type: Java class of the event
To receive an event, its type must match
post(new MyEvent());
onEvent(MyEvent event) {…}
Type hierarchy of events
– Implement logging of all events:
onEvent(Object event)
15. Event Type is a Filter
Subscriber
Event
Event Event onEvent(MyEvent)
Publisher
post Bus
(MyEvent)
Subscriber
onEvent(OtherEvent)
18. EventBus Code: Receiver
MyActivity extends Activity // no interf.
// onCreate or onResume
EventBus.getDefault().register(this);
// onDestroy or onPause
EventBus.getDefault().unregister(this);
public onEvent(MyEvent event) { … }
19. Example: Fragment to
Fragment
Tap on one fragment
Another fragment reacts
Typical list/details scenario
Conventional setup: Activity
Activity is managing
Fragments
Fragment Fragment
26. Why do Threads matter?
Responsive UI, Android conventions
– Main/UI thread must not block
– UI updates in the main thread
– Networking etc. in background threads
Threads and Events
– Thread posting events
– Thread handling events
– Posting and handling thread may differ
27. EventBus Threading Support
Event delivery using threads
Event handler method decides
(handler knows best what it is doing)
Naming conventions for onEvent methods
To deliver in the main thread:
onEventMainThread(…)
(All methods beginning with onEvent are
checked for typos)
28. Thread Modes
PostThread: Direct call in same thread
MainThread: UI updates etc.
BackgroundThread: „not the main
thread“
Async: always asynchronous to posting
Used in the method name: onEventXXX
No additional code required
29. Threading Example
Network thread posts result
post(new UserLoginEvent(name));
Fragment reacts to event in main thread
public void
onEventMainThread(UserLoginEvent e) {
textView.setText(e.getName());
}
31. Upcoming: EventBus 2.1
EventBus 2.1 is not final yet;
Still gathering experience and feedback
Everything pushed to master branch
No relevant changes in the core (planned)
Comes with some helpers
– AsyncExecutor
– Error dialog
32. EventBus 2.1: AsyncExecutor
A thread pool, but with failure handling
RunnableEx interface
– Like Runnable to define code to run async.
– May throw any execption
ThrowableFailureEvent
– Posted when exception occurs
– Throwable object is wrapped inside
– Subclass to customize and filter for type
36. EventBus 2.1: Error Dialog
Operations may fail (networking, etc.)
Some UI response should be shown
– Currently: error dialogs
– Later: Possibly maybe someth. Crouton-ish
Multiple errors: don‟t open multiple times
Goal: Minimize required code
37. How Error Dialogs work
Error handling “attaches” to Activities
Displaying dialogs is triggered by events
ThrowableFailureEvent or subclass
– AsyncExecutor sends those
– Or post those events manually
38. Error Dialogs: Code
// In onCreate in your Activity
ErrorDialogManager.attachTo(this);
// Trigger the dialog
bus.post(new ThrowableFailureEvent(ex));
// Or let AsyncExecutor do it for you…
39. Dialog Configuration
Which texts to display in the dialog?
Simple option: Configure
– Supply default resources for title and text
– Map exception types texts
Flexible option: extend
ErrorDialogFragmentFactory
40. Dialog Configuration: Code
// Initialize in your Application class
ErrorDialogConfig config = new
ErrorDialogConfig(getResources(),
R.string.error_generalTitle,
R.string.error_general);
config.addMapping(UnknownHostException.class,
R.string.error_noInternetConnection);
config.addMapping(IOException.class,
R.string.error_generalServer);
ErrorDialogManager.factory = new
ErrorDialogFragmentFactory.Support(config);
41. Comparison Android
Broadcast
Nice, but somewhat inconvenient
BroadcastReceiver has to be extended
Registration needed for every event type
Extra work to filter for desired event types
(IntentFilter with e.g. ACTION String)
Data is converted into Intent extras
43. Sticky Events
Events can be posted using sticky mode
postSticky(event); // Instead of post(…)
The last sticky event is kept in memory
Registration with getting sticky events
registerSticky(subscriber);
Query for sticky event
getStickyEvent(Class<?> eventType)
Remove sticky event (Class or Object)
removeStickyEvent(Class<?> eventType)
44. Events Class
Event classes are tiny; group them
public class Events {
public static class InitThreadCompleteEvent {
}
public static class LoginCompleteEvent {
}
}
45. EventBusFragment/-Activity
Superclass depends on your setup
Implement in your project
class EventBusFragment extends Fragment {
public void onCreate(…) {
super.onCreate(…);
EventBus.getDefault().register(this);
}
public void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
46. When to use EventBus
Medium/high distance of components:
“Somewhere” else should happen sth.
Potentially multiple dependencies
Asynchronous logic
When not to use EventBus
– Strictly internal matters:
Use methods and interfaces instead
– Inter-process communication
47. License, Contact
This presentation is licensed under
CreativeCommons ShareAlike/Attribution
http://creativecommons.org/licenses/by-sa/3.0/
Contact greenrobot
– http://greenrobot.de
– http://twitter.com/greenrobot_de
– Google+: http://bit.ly/greenrobotplus