The outline
EventBus is an EventBus framework based on an event publish/subscribe mechanism that simplifies Android event delivery by decoupling publishers and subscribers. You can communicate flexibly before the four components, or you can specify a thread model for communication between different threads.
EventBus: making the address
The basic concept
EventBus consists of three main elements:
- Event – the Event
- The Publisher, Publisher
- The Subscriber, the Subscriber
After registering register(), Subscriber defines the Event receiving method through the @subscribe annotation to receive events issued by Publisher. The sending and receiving of events can be used across threads.
EventBus has the advantage over Android’s traditional messaging mechanism in that it is simpler, more efficient, and supports flexible thread switching.
configuration
-
Depend on the configuration
implementation("Org. Greenrobot: eventbus: 3.3.1") Copy the code
-
Confuse configuration
-keepattributes *Annotation* -keepclassmembers class * { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } # If using AsyncExecutord, keep required constructor of default event used. # Adjust the class name if a custom failure event type is used. -keepclassmembers class org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable); } # Accessed via reflection, avoid renaming or removal -keep class org.greenrobot.eventbus.android.AndroidComponentsImpl Copy the code
use
Simple to use
-
Register/Unregister
Subscribers need to register before receiving events, which are usually lifecycle dependent, such as onCreate() registration in an Activity and onDetroy() deactivation. (Of course, you can put it into other lifecycle methods depending on your business scenario.)
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?). { super.onCreate(savedInstanceState) setContentView(R.layout.activity_second) registerEvent() } override fun onDestroy(a) { super.onDestroy() unRegisterEvent() } /** * Register */ private fun registerEvent(a){ EventBus.getDefault().register(this)}/** * cancel */ private fun unRegisterEvent(a){ EventBus.getDefault().unregister(this)}}Copy the code
-
Event definition/send
EventBus supports the sending of any type of event, and subscribers process the event according to the event type. Events are usually defined as the event class at the end of xxxEvent. If you want to process different events, you must define different event classes.
class StringEvent internal constructor(var msg: String) { internal fun getMsg(a) = msg internal fun setMsg(msg: String){ this.msg = msg } } Copy the code
-
Specify the event receiver method through annotations
The subscriber’s event receiving method needs to be defined with the @subscribe () annotation, defined in the Activity:
@Subscribe(threadMode = ThreadMode.MAIN) fun event(event: StickyEvent){ // Displays the received events textView3.text = event.msg } Copy the code
Set the thread model to threadmode. MAIN so that the UI can be modified directly because it runs in the MAIN thread.
Threading model
EventBus supports several threading models, which specify the threads in which the subscriber processes the implementation, depending on the usage scenario. For example, if you modify the UI above, you can specify the MAIN thread.
ThreadMode specifies the thread model
@Subscribe(threadMode = ThreadMode.MAIN)
fun event(event: StickyEvent){
// Displays the received events
textView3.text = event.msg
}
Copy the code
- ThreadMode.POSTING
- Default thread model
- The receiver is on the same thread as the publisher, events are delivered synchronously, and all event subscribers receive event messages synchronously.
- Reuse the same thread, low overhead.
- ThreadMode.MAIN
- The receiver is called in the UI main thread.
- If the publisher is a UI thread, the subscriber does not start a new thread; if not, a new thread is started to handle subscriber events.
- Because it’s a UI thread, you can modify the UI directly, but you can’t do time-consuming operations.
- ThreadMode.MAIN_ORDERED
- The receiver is called in the UI main thread.
- The receiver processes events sequentially, with the second one receiving execution only after the first one has completed.
- You can also modify the UI directly, but you can’t do time-consuming operations.
- ThreadMode.BACKGROUND
- Background processes, subscriber events are always processed in background threads.
- If the sender is a UI thread, the receiver will create a new thread for processing, otherwise it will be processed in the same thread.
- ThreadMode.ASYNC
- Asynchronous threads always start a new thread to handle the receiver event to ensure that the receiver and publisher are always on different threads.
- Internal use of thread pool for processing, saving resource overhead.
Viscous event
Normal events need to be subscribed before they can receive events that are sent later. Sticky events can receive previously sent events after registering for a subscription. This means that once an event is sent, it can be received by subscribers who sign up later.
Use:
-
send
// Use postSticky() to send sticky events val event = StickyEvent("Sticky event") EventBus.getDefault().postSticky(event) Copy the code
-
receive
// Sticky event reception, also need to add sticky = true in annotation @Subscribe(threadMode = ThreadMode.MAIN, sticky = true) fun event(event: StickyEvent){ textView3.text = event.msg } Copy the code
Note that EventBus handles different events by event type. If a sticky event of the same type is sent multiple times, EventBus will only keep the last sticky event.
Because of the specificity of sticky events, the same event may be processed repeatedly. Sticky events that do not need to be processed can be removed by the following methods:
// Remove sticky events
EventBus.getDefault().removeStickyEvent(stickyEvent)
Copy the code
summary
- advantage
- Simple, easy to use, powerful.
- It’s more efficient than broadcasting.
- disadvantage
- The implementation is simple and easy to abuse.
- Implementation friendly, poor readability.
- In order to receive events, a large number of Event classes need to be defined, which is difficult to manage in the later stage.
- The support for multiple modules similar to component-based development is not good. The Event class needs to be sunk into the underlying module, which destroys module independence and increases module coupling.
- Powerful, easy to lead to software architecture design deviation, especially large projects should be designed according to the idea of interface programming.
extension
Other buses:
- RxBus, a single class with just a few dozen lines of code, implements the same powerful event bus functionality and is based on the same powerful Rxjava, which is the best choice if your project already uses Rxjava.