EventBus literal translation is an event bus, which uses the publish-subscribe model supports communication between components, do not need to explicitly register a callback, more flexible than the observer pattern, can be used to replace traditional Java event listener model, the role of the solution is EventBus coupling, it is not a generic publish-subscribe system can not be used for inter-process communication. EventBus libraries are available for Android are mainly these: Google produced Guava, Guava is a huge library, EventBus just a small feature that comes with it, so the actual project is not much use. Most are used greenrobot / EventBus, the advantage of this library is the interface simple and easy to integrate, but defines a method name, does not support annotations. Another library square / otto modified from Guava, with a lot of people.
To greenrobot / EventBus for example, we look at the typical usage pattern EventBus:
// Register EventBus, to accept events
class Fragment {
public void onCreate(){
EventBus.getDefault().register(this);
}
public void onDestroy(){
EventBus.getDefault().unregister(this);
}
public void onEvent(SomeEvent1 event){
// handle event
}
}
// processing tasks, send event
public class Service {
public void doSomeThing(){
// do your work
// send event
EventBus.getDefault().post(new SomeEvent1());
}
Several issues EventBus in?
- Event Definition: Any object can be;
- Registered event handlers: Methods event handling, you can add annotations, then the object event handler registered to the bus, the bus maintaining the correlation between an event and the event handler, in memory;
- Processing of events: Synchronous processing and asynchronous processing, after the event submission, the event queue maintained in the local cache, synchronized direct current thread to perform asynchronous processing strategy is in the initialization event bus will engage in a thread pool out to the thread pool asynchronous execution;
- EventBus to open three methods,register/post/unregister
- Why unregister? 99.99% of the usage scenario, is not going to register / unregister an observer at runtime when the environment in the spring, but also do register / unregister at the time of init. But we do consider this framework it is necessary to 0.01% of usage scenarios.
A, Guava EventBus observer mode
First, we declare an Observer:
public class EventObserver {
@Subscribe public void onMessage(Message message) {
...
}
}
This class does not inherit any interface, just to declare a method @Subscribe the response notification.
EventBus very simple to use, a first statement:
EventBus eventBus = new EventBus();
Then, we have written into the registration Observer:
eventBus.register(new EventObserver());
When to notify Observer, so long as we can:
eventBus.post(message);
Here, we do not tell EventBus, we are dealing with is a Message type, but the use of this type on the interface declaration onMessage method EventObserver only. However, when we send out the message, it will be matched according to type, to ensure that our local news transmitted correctly to the corresponding.
Compared to the original implement JDK, this implementation will be easier. EventObserver no longer requires the presence of a system of inheritance, and inheritance is always a yoke of us stuck in a system:
- We do not have to follow a specific name, such as the Observer update, and here is our own name onMessage played.
- We do not follow a particular type, such as an update method and the observed object Observable Object as a parameter, but according to our own needs to choose the type.
This transformation let statically typed language Java, have some type of dynamic characteristics, but also let the program more flexible. This flexibility is mostly thanks to Annotation, it affects the Java programming style to a large extent.
In addition to standard EventBus, Guava also provides another AsyncEventBus, can be seen from the name, this is an asynchronous EventBus, that is to say, after news thrown at it, will return immediately, as the Observer when treatment is that it thing. When the time-consuming processing is useful, we have to rely Executors to implement asynchronous event bus.
AsyncEventBus eventBus = new AsyncEventBus("test", Executors.newCachedThreadPool());
Also: Use on EventBus, see:http://blog.mcxiaoke.com/2015/08/03/how-to-write-an-eventbus-part1/
Second, the example
1, the definition of an event (any object can be an event)
public class SignEvent {
private String companyName;
private String signName;
private Date signDate;
public SignEvent(String name,String signName, Date signDate) {
super();
this.companyName = name;
this.signName = signName;
this.signDate = signDate;
}
public String getMessage(){
StringBuilder sb = new StringBuilder();
. Sb.append ( "Logistics:") append (this.companyName);
. Sb.append ( "the person who signed:") append (signName) .append ( ", receipt date:"). Append (signDate);
return sb.toString();
}
}
2, defines two event listeners, add annotations to do an event subscription
public class YTOEventListener {
@Subscribe
public void consign(SignEvent signEvent){
if(signEvent.getCompanyName().equalsIgnoreCase("YTO")){
System.out.println ( "YTO ... start shipping");
System.out.println(signEvent.getMessage());
}
}
@Subscribe
public void delivery(SignEvent signEvent){
if(signEvent.getCompanyName().equalsIgnoreCase("YTO")){
System.out.println ( "YTO ... start delivery");
}
}
}
public class SFEventListener {
@Subscribe
public void consign(SignEvent signEvent){
if(signEvent.getCompanyName().equalsIgnoreCase("SF")){
System.out.println ( "SF ... start shipping");
System.out.println(signEvent.getMessage());
}
}
@Subscribe
public void delivery(SignEvent signEvent){
if(signEvent.getCompanyName().equalsIgnoreCase("SF")){
System.out.println ( "SF ... Start delivery");
}
}
}
3, EventBus examples, including the time of submission of registration and events
public class EventBusTest {
public static void siginalThreadConsumer(){
EventBus bus = new EventBus("iamzhongyong");
SFEventListener sf = new SFEventListener();
YTOEventListener yto = new YTOEventListener();
bus.register(sf);
bus.register(yto);
SignEvent sign1 = new SignEvent ( "SF", "Bichon ah", new Date ());
bus.post(sign1);
SignEvent sign2 = new SignEvent ( "YTO", "your sister", new Date ());
bus.post(sign2);
}
public static void multiThread(){
EventBus bus = new AsyncEventBus(Executors.newFixedThreadPool(3));
SFEventListener sf = new SFEventListener();
YTOEventListener yto = new YTOEventListener();
bus.register(sf);
bus.register(yto);
SignEvent sign1 = new SignEvent ( "SF", "Bichon ah", new Date ());
bus.post(sign1);
SignEvent sign2 = new SignEvent ( "YTO", "your sister", new Date ());
bus.post(sign2);
}
public static void main(String[] args) {
EventBusTest.siginalThreadConsumer();
EventBusTest.multiThread();
}
}