介紹
1.什么是EventBus
想必每個入了門的Android開發者都多少對EventBus有過了解,EventBus是一個Android事件發布/訂閱框架,通過解耦發布者和訂閱者簡化 Android 事件傳遞。
EventBus 直譯過來就是事件總線,它使用發布訂閱模式支持組件之間的通信,不需要顯式地注冊回調,比觀察者模式更靈活,可用于替換Java中傳統的事件監聽模式,EventBus的作用就是解耦,它不是通用的發布訂閱系統,也不能用于進程間通信。
最近EventBus剛好更新了3.0版本,事件的訂閱已經從方法名換成了注解的方式。3.0版本將粘性事件以及訂閱事件的優先級換了一種更好的實現方式,所以3.0版本中的注冊就變得簡單,只有一個register()
方法即可.
使用 EventBus3.0
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
public void onEventBus(View view) {
EventBus.getDefault().post(new Student(12, "helen"));
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvenHaha(Student student) {
Log.d(TAG, "ThreadMode.MAIN:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void onEventPost(Student student) {
Log.i(TAG, "ThreadMode.POSTING:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEventBackground(Student student) {
Log.w(TAG, "ThreadMode.BACKGROUND:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
}
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onEventAsyn(Student student) {
Log.e(TAG, "ThreadMode.ASYNC:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
post一個obj,在ui線程。結合文檔ThreadMode.java 的說明,可以知道:
原理概述
EventBus解耦的方式其實是使用了反射,我在調用register()方法的時候,獲取到Subscription對象,EventBus就掃描調用Subscription類,將需要反射調用的方法信息記錄下來,這些方法就是
onEvent(),
onEventMainThread(),
onEventBackgroundThread()
onEventAsync()。
這些方法被記錄以后,如果有人調用post()方法,就會在記錄里面查找,然后使用反射去觸發這些方法。反射觸發方法的方式是調用Method類的invoke()方法。
public Object invoke(Object obj, Object... args)
顯然要我們需要1,Method對象,訂閱者對象obj,還有參數對象args
也就是說記錄里面,對應一個訂閱方法,起碼要有上面三個參數。
- 我們在register()的時候,目的是獲得Subscription對象
- 我們在post(Object obj)的時候,目的是將傳入的obj和相應的Subscription對象一起封裝成PendingPost對象
將其放入隊列里面排隊,隊列會不斷取出元素,觸發反射!
掃描方法
你只要記得一件事:掃描了所有的方法,把匹配的方法最終保存在subscriptionsByEventType(Map,key:eventType ; value:CopyOnWriteArrayList<Subscription> )中;
eventType是我們方法參數的Class
Subscription中則保存著subscriber, subscriberMethod(method, threadMode, eventType), priority;包含了執行改方法所需的一切。