Why implement the event bus with LiveData?

LiveData is an observable data store class. Unlike regular observable classes, LiveData has lifecycle awareness, meaning that it follows the lifecycle of other application components such as activities, fragments, or services. This awareness ensures that LiveData updates only application component observers that are in an active lifecycle state.

LiveData has life cycle awareness to ensure that the interface conforms to the data state, there is no memory leak, there is no crash caused by Activity stop, there is no need to handle the life cycle manually, and the data is always up to date

I’m not going to do much more on LiveData, there are a lot of detailed articles on LiveData, but how do you implement the event bus using LiveData

The difficulty of implementing the event bus with LiveData is that LiveData is designed to be a sticky event in order for it to automatically rewind the last data it observed after the view controller has been rebuilt. I read a lot about LiveDataBus before that. As for the implementation of non-sticky LiveData, there are two ways to solve the problem on the Internet: “event wrapper class” and “reflection intervention LastVersion”.

Does the implementation of LiveDataBus really need so much trouble? No, I don’t think so.

Let me share with you my implementation ideas

Define a HashMap to hold the different message channels
 private valliveDataMap = HashMap<String, MutableLiveData<Any? > > ()Copy the code

LiveData is designed as a solution to sticky events in order to automatically rewind the last observed LiveData after a view controller reconstruction

Solution:

To avoid receiving duplicate events, the solution I use here is to replace the original MutableLiveData with a new MutableLiveData each time a configuration change occurs. The last MutableLiveData message will not be received, but multiple subscriptions only need to use different tags, otherwise only the last place to subscribe will be received

 fun with(tag: String): LiveData<Any? >? { liveDataMap.put(tag,MutableLiveData())return liveDataMap[tag]
 }
Copy the code
Subscribe to events that update only application component observers in the active lifecycle state

LiveDataBus.with(tag).observe(this, Observer {
         // Received the message
})

Copy the code

Observe only updates application component observers that are in the active lifecycle state when subscribed. if required, observeForever will be notified whenever data is updated, meaning that a given observer will receive all events and will never be automatically deleted. You need to manually call removeObserver(Observer) to stop this LiveData


/**
     * Adds the given observer to the observers list. This call is similar to
     * {@link LiveData#observe(LifecycleOwner, Observer)} with a LifecycleOwner, which
     * is always active. This means that the given observer will receive all events and will never
     * be automatically removed. You should manually call {@link #removeObserver(Observer)} to stop
     * observing this LiveData.
     * While LiveData has one of such observers, it will be considered
     * as active.
     * <p>
     * If the observer was already added with an owner to this LiveData, LiveData throws an
     * {@link IllegalArgumentException}.
     *
     * @param observer The observer that will receive the events
     */
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if(existing ! =null && existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if(existing ! =null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }
Copy the code
Subscribe with observeForever, not affected by the life cycle, and will be notified whenever data is updated

LiveDataBus.with(tag).observeForever(this, Observer {
         // Received the message
})

Copy the code
Event sending

fun send(tag: String, t: Any? = null) {
    if(! liveDataMap.containsKey(tag) )returnliveDataMap[tag]? .postValue(t) }/ / send
LiveDataBus.send(tag)

Copy the code
The source code for LiveDataBus can be copied or downloaded from the author’s GitHub repository:

Github.com/BugRui/Live…