Android EventBus and observer mode

A brief introduction to the observer mode

The observer mode is also known as the publish/subscribe mode. The observer mode defines a one-to-many dependency relationship, allowing multiple observer objects to monitor a certain subject object at the same time. This subject object will notify all observer objects when the state changes, so that they can update themselves automatically. This mode is widely used, such as in Android: 1. The
content provider of the Android system, the content observer adopts this observer mode.
2. The Adapter of RecyClerView and ListView uses the observer mode.
3. When two interfaces want to observe the download progress at the same time, the observer mode can be used to decouple.

Implementation steps
1. Define an observer interface Observer, the observer implements the observer interface ObserverA implements Observer.
2. Define an Observed interface Subject, and the Observed implements the Observed SubjectDemo implements Subject.
3. When the observer changes, call the notification method and call back the method in the Observer.

Sample code:
1.
Public interface Subject { //Add observer void addObserver(Observer observer); //Remove the specified observer void removeObserver(Observer observer); //Remove all observers void removeAll (); //Notify all observers, data is the data to be notified to observers, Object is the parent of all classes, polymorphism can be used, of course you can also use generic void notifyAllObserver(Object data); //notify A certain observer void notify(Observer observer,Object data); }










2. Observer interface
public interface Observer { // This method is to notify the observer to update. Parameter 1: subject is the observer. Parameter 2: data is the data passed by the observer to the observer void update(Subject subject, Object data ); }




3. Implement the interface and define specific observers and observers

public class SubjectDemo implements Subject {
List mList = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
// 确保相同的观察者只含有一个
if (observer == null) {
throw new NullPointerException(“observer == null”);
}
if (!mList.contains(observer)) {
mList.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
mList.remove(observer);
}
}

@Override
public void removeAll() {
mList.clear();
}

@Override
public void notifyAllObserver(Object data) {
for (Observer observer : mList) {
observer.update(this,data);
}
}

@Override
public void notify(Observer observer, Object data) {
if(observer!=null){
observer.update(this, data);
}
}

}

public class ObserverA implements Observer {
@Override
public void update(Subject subject, Object data) {
System.out.println( data+“我玩甄姬”);
}
}

public class ObserverB implements Observer {
@Override
public void update(Subject subject, Object data) {
System.out.println( data+“我玩兰陵王”);
}
}

3. The client calls
SubjectDemo subjectDemo = new SubjectDemo();
ObserverA observerA = new ObserverA();
ObserverB observerB = new ObserverB();
subjectDemo.addObserver(observerA);
subjectDemo.addObserver(observerB);
subjectDemo.notifyAllObserver("Tonight Open black together");

Observer pros and cons

Advantages
It decouples the informer and the observer very well. The observer does not need to understand how the informer is implemented internally, which is convenient for future code modification and reflects the principle of dependency inversion.

Disadvantages: The
abstract informer (namely: the subject of the observed interface) still relies on the abstract observer (namely: the observer interface of Observer), when there is no observer, there is no way to update. Because there is an observer method in the Subject interface, this method passes the Observer interface as a parameter, otherwise the observer cannot be notified to update the data.
. All behaviors of observers are required to be consistent. (That is: the specific observer must implement all methods in the observer interface Observer)

What is the dependency inversion principle
Simply put, the dependency inversion principle requires the client to rely on abstract coupling. The expression of the dependency inversion principle is: abstraction should not depend on details, and details should depend on abstraction. Another expression is: to program for the interface, not for the implementation.
Types of dependency relationships:
1) Zero coupling relationship: If there is no coupling relationship between the two classes, it is called zero coupling
2) Specific coupling relationship: Specific coupling occurs between two concrete classes (instantiable) through one A direct reference of a class to another class is caused.
3) Abstract coupling relationship: Abstract coupling relationship occurs between a concrete class and an abstract class (or java interface), so that there is maximum flexibility between two classes that must have a relationship.

What is EventBus

EventBus is a publish/subscribe event bus optimized for Android. The main function is to replace Intent, Handler, and BroadCast to pass messages between Fragment, Activity, Service, and threads. The advantage is that the overhead is small and the code is more elegant. To achieve low-coupling event communication between multiple modules, that is, to decouple the sender and the receiver.
After EventBus 3.0, the method name can be specified arbitrarily, but @Subscribe annotations need to be added. In the annotations, you can specify the thread model, whether to support sticky events, and priority.
Sticky events: send the event first, and then register the subscriber, you can also receive the event.
Ordinary event: the subscriber must register first, and then send the event, in order to be received by the subscriber.

Under Android, thread switching is a very common and necessary operation. In addition to subscribing and sending messages, EventBus can also specify the thread that receives messages and processes messages.
In other words, no matter what thread you are in when you post() the message, EventBus can distribute the message to the thread you specify, which sounds very convenient.
However, no matter how you switch, there are several situations:
• UI thread cuts child threads.
• The child thread cuts the UI thread.
• The child thread cuts other child threads.
When we use EventBus to register messages, we can use the @Subscribe annotation to complete the event registration. In @Subscribe, we can use the parameter threadMode to specify which thread to use to receive messages.
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventTest(event:TestEvent){ // handle event }

threadMode is an enum, there are multiple modes to choose from:
1. POSTING, the default value, which thread sends is which thread receives.
2. MAIN, switch to the main thread to receive events.
3. MAIN_ORDERED, a new attribute added in v3.1.1, also switches to the main thread to receive events, but it is slightly different from MAIN. If the event is sent in the main thread, it will be executed directly if the event is sent in the main thread. In order to make the development and configurability higher, use MAIN_ORDERED, it will not distinguish the current thread, but will use the mainThreadPoster to deal with it, which is bound to go through the message distribution of the Handler.
4. BACKGROUND, to ensure that events are received in the child thread. The details are that if the message is sent by the main thread, it will switch to the child thread to receive it, and if the event itself is sent by the child thread, the thread that sent the event message will be used directly to process the message.
5. ASYNC, to ensure that the event is received in the child thread, but the difference from BACKGROUND is that it does not distinguish whether the sending thread is a child thread, but receives events in a different thread each time.

In short

  1. EventBus can configure the thread that receives the event through threadMode.
  2. Both MAIN and MAIN_ORDERED will receive events on the main thread. The difference lies in whether they are distinguished and whether the thread where the event occurs is the main thread.
  3. BACKGROUND To ensure that the thread is received in the child thread, it will pass through the thread pool and use a thread loop to process all events. Therefore, the execution timing of the event will be affected by the efficiency of event processing in front of the event queue.
  4. ASYNC ensures that events are received in child threads. Unlike BACKGROUND, ASYNC will send tasks to the thread pool every time and execute them through the thread pool scheduling. However, because the thread pool uses an unbounded queue, it will lead to OOM when there are too many ASYNC pending events.

The relationship between EventBus and the observer pattern

EventBus is a message processing framework based on the observer pattern. All require subscription time, publishers publish information, and subscribers update information in time.
1. The advantage of the observer mode is that it is more flexible, and you can customize the interface of your own business according to your needs. At the same time, there are no too many restrictions in activity, fragment, and service, perfect decoupling.
2. The advantage of EventBus is that you don't need to spend a lot of time to encapsulate by yourself, which improves development efficiency.

Guess you like

Origin blog.csdn.net/yanhuomatou2015/article/details/108787210