I originally published this series of articles in Jane’s Book. He recently moved on to the Nuggets. – It will be published in nuggets in the future.

EventBus and Otto were popular for their simplicity as communication tools between Android components, but they were also easy to Abuse. It probably has the following disadvantages:

  • Because it’s an Event, you have to be prepared when you post an Event that maybe no one will accept it, and you have to be prepared when you Subscribe that you will never receive an Event. Events are somewhat out of control both in order and time. If you put data on an Event then use that data or member variables directly in other Android lifecycle methods. So you’re probably going to get an NPE.
  • EventBus seems to decouple your program, but it goes too far. We often use EventBus to transfer data, which is already Dependency level data rather than a module that can be decoupled. As a result, too much Code for EventBus can result in a messy code structure that is difficult to test and track, defeating the purpose of decoupling. In this case, a Nested Event is intentionally or unintentionally caused. It would have been worse.

Because of the shortcomings of EventBus, and later the advent of RxJava. Many people are starting to use RxJava instead of EventBus. Even Otto’s official introduction says:

Deprecated!

This project is deprecated in favor of RxJava and

RxAndroid. These projects permit the same event-driven

programming model as Otto, but they’re more capable and offer better control of threading.

If you’re looking for guidance on migrating from Otto to Rx, this post

is a good start.

The link is to an article that teaches you how to use RxJava to manually write an RxBus instead of EventBus yourself. Although it looks like you’re using RxJava. But you’re still using EventBus. Even this package isn’t as good as GreenRobot or Otto. Let’s take a look at Jake Wharton’s assessment of RxBus:



I guess the only good thing about “RxBus” is that he’s a gateway drug to Rx. Otherwise, you’re either not using Rx, or you need more conventional Rx resources

Here’s another one from GitHub:

So we’re not going to consider the subscribeActual part. Jake, however, points out that it’s best not to use Relay to “reinvent” the Event Bus.

Jake Wharton, in his talk at GOTO 2016, said that our normal Android programming looks like this:













For example, although we translate EventBus as time Bus, Bus is actually Bus. RxJava is more like a private car, Uber or Didi. It links directly to two or more of your classes that need to communicate. To transfer data, of course you can have a big private car that goes between all the classes, what’s called an RxBus. So why abandon RxBus here is self-evident no?

So, the question?

What is right (normal?) How to use RxJava?

In fact, Jake also gave an answer on the GitHub discussion:

So, whenever you want to publish an Event in EventBus, expose an Observable. Whenever you want to accept an Event, find the Observable and Subscribe to it.

What are the benefits of this?

  • The target and the location are clear. Your Subscriber clearly knows who he subscribes to and what response I need to make. This is the “responsive programming” at the heart of RxJava.
  • Observable makes exception handling very convenient. There is also a powerful and comprehensive Operator to assist you.
  • Although there seems to be an increase in coupling. But it’s necessary, and as mentioned above, EventBus looks decoupled in code. In fact, they are linked. We expose the Observable directly to the other classes we want, which completes the 1 -> 1/N link without the middleman of EventBus passing messages/events, and ensures that the events we want will arrive directly.

Let’s take an example

2 fragments, top EditText, bottom TextView. The top EditText changes and the bottom TextView changes as well.

Wrap the EditText TextChangedListener in an Observable:

        stringObservable = Observable.create(e -> editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                e.onNext(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        }));

/ * * * * * * /
    //Expose Observable
    public Observable<String> getEditTextObservable() {
        return stringObservable;
    }Copy the code

If you are not used to wrapping yourself, you can use RxBinding:

        stringObservable = RxTextView.textChangeEvents(editText)
                                     .map(event -> event.text().toString());Copy the code

Get this wrapped Observable from our TextViewFragment:

    @Override
    public void onStart() {
        super.onStart();
        FragmentEditText fragment = (FragmentEditText) getFragmentManager().findFragmentByTag(FragmentEditText.TAG);
        if(fragment ! =null){ fragment.getStringObservable().subscribe(s -> textView.setText(s)); }}Copy the code

Take a look at the results:

There’s a problem, of course

  • Since we wrap the editText in an Observable, either the Create () method or the RxBinding holds a strong reference to the View. Memory leaks occur. So we must add dispose() method at the end to release. Therefore, I recommend using RxBinding. He has already written the method to remove the Listener in his dispose() method.
  • Because the publish operator is not used, there are still some problems with multiple Subscriber. Consider joining.share() directly.

Conclusion:

I saw this reply from someone on Reddit the other day:

I think EventBus on android is popular because people don’t know how to share a java object reference between android components like a Fragment and an Activity, or 2 Activities and so on. So basically I think people don’t know how 2 Activites can observe the same object for data changes which I think comes from the fact that we still don’t know how to architect our apps properly.

I think EventBus is popular on Android because people don’t know how to share references to Java objects between Android components such as Activities/Fragments.

This response should have touched a sore point for many people. In many cases we use EventBus simply because we don’t know how to share an object between multiple Fragments/activities. EventBus does this by registering all recipients in the Bus. This similar in RxJava, Subject/ConnectableObservable have similar features. The problem is that EventBus, as a global Bus, can be cumbersome to manage different types of events (although EventBus does this for you, RxBus does it itself). With RxJava, we can completely avoid the management of different events. The same event is encapsulated into the corresponding Observable, and the subscription is selected as required. This keeps type safety, improves performance, and makes logic clearer.

Is that why you use EventBus?

Text of mining technology