Why do I need the EventBus library or its Otto counterpart?


I looked through a lot of links in Google, but still did not get a specific answer: what task does the Greenrobot EventBus library solve (or its analogues - Square Otto), how is it better than the standard options, and how does it justify its use?


The last question arises from the fact that I do not imagine such an architecture built on events. In MVP\RxJava, the library does not fit at all (at least, in its own projects I haven't seen any places to use them), unless it makes sense to use the library in communication between Service and other parts of the application.

Author: αλεχολυτ, 2015-11-30

2 answers

If you ignore all the tricky terms, like event-oriented programming, then this library is used to organize communications (exchange of data and events) between unrelated parts of the application.
That is, this library allows you to send arbitrary data from one part of the application (for example, activity) to another (for example, a fragment) in the simplest way.
The work is based on registering the receiver of the event and then sending some events "on the air". The desired receiver will receive its signal and you can accept the sent data. Example:

First, a model class is created with initialization constructors, which will store the transmitted data:

public class MessageEvent {
    public final String message;

    public MessageEvent(String message) {
        this.message = message;
    }
}

Here is a model class MessageEvent with a single data field of type String and a constructor for initializing this data. You can create an arbitrary number of data fields of arbitrary objects, and initialization constructors can include multiple arguments.

Then in the classroom (for example, an activity) from which you need to pass our data, an event is created:

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

In the class where we want to send our data (for example, a fragment) we register the event receiver:

    @Override
    public void onStart() {
        super.onStart();
        // регистрация приемника при старте фрагмента
        EventBus.getDefault().register(this);
    }

    @Override
    public void onStop() {
        // отписываемся от регистрации при закрытии фрагмента
        EventBus.getDefault().unregister(this);
        super.onStop();
    }

    // В этом методе-колбэке мы получаем наши данные 
    // (объект `event` типа класса-модели MessageEvent)
    public void onEvent(MessageEvent event){
        // извлекаем из модели отправленную строку: event.message = "Hello everyone!"
        Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
    }

As soon as the event sending code is executed in the activity, the sent data will appear in the callback onEvent() of the fragment. Only those receivers that have the same signature in the callback as the sent event will receive this data.
In addition to model classes, you can also pass simple classes. data types, for example:

Sending:

 int num = 5;
 EventBus.getDefault().post(num);

Receiving (receiver registration omitted):

 public void onEvent(int event){
            Toast.makeText(getActivity(), "Получено число:" + event, Toast.LENGTH_SHORT).show();
    }

In general, it does not matter what you send over the bus: classes-models of a complex structure, objects, collections, arrays , or primitive types - all this will be delivered to the recipient in one piece.

From the data exchange tools that the Android system itself implements, this solution is favorably distinguished by the simplicity and transparency of use, the absence of any connection between sender and receiver, and the ability to transmit data of any type and in any quantity without any partitioning or serialization.

The library also allows you to send "sticky" events (they will not disappear until other data is sent, for example, when transmitting between two activiti, when the receiver does not exist at the time of transmitting the event, the data will be received when the receiver appears), work with asynchronous threads, and so on. See the documentation for details.

There are also other libraries with similar functionality, such as Square Otto.
In addition, the concept of reactive programming has gone much further - the framework RxJava and the add-ons for Android-the framework RxAndroid, which takes into account the specifics of the platform.

 53
Author: pavlofff, 2017-04-22 04:44:41

For code decomposition.
Let's say you have an activity + several fragments, without a "bus" , you throw kalbacks from the activity, or inside the fragment, go to the activity class (or the interface that this activity implements) and call the methods. With the bus, you subscribe to events in activiti and post events from fragments. The code about the callbacks goes away, less code is clearer. Interfaces are "decoupled" fragments are easier to reuse in other activities.
Or another example with business logic, write as a separate module that knows nothing about the UI and communicates with it via the event bus. Less dependencies - clearer code, when testing, we replace the UI with test code that posts/subscribes to events related to business logic.
That is, all this will not make your code faster, you will not consider the task better. All this is rather a matter of "faith", in the sense of the development methodology. By and large, all techniques in programming (functions, OOP, etc.) are about the decomposition of the problem. You have a big one a task, you break it down into small subtasks. The more isolated the submodule is from the others, the clearer it is.
I use a similar library in my project http://square.github.io/otto/ + dependency injection http://square.github.io/dagger/ It turns out nice.
But again, all this is a personal choice of the programmer/team. Allows you to write more clearly? - We use it. That is, not that "here is an event bus and we all take it in formation and use it everywhere".

 22
Author: hardsky, 2015-12-01 01:40:05