經過對多個有關事件總線模式的文檔介紹的閱讀,對事件總線模式有了一定的了解,并作出如下總結:
事件總線模式主要是處理事件,包括4個主要組件:事件源、事件監聽器、通道和事件總線。消息源將消息發布到事件總線上的特定通道上。偵聽器訂閱特定的通道。偵聽器會被通知消息,這些消息被發布到它們之前訂閱的一個通道上。
使用場景:安卓開發、通知服務
優點:新的發布者、訂閱者和連接可以很容易地添加。對高度分布式的應用程序有效。
缺點:可伸縮性可能是一個問題,因為所有消息都是通過同一事件總線進行的。
事件總線的處理流程:
實例:事件總線模式是一種廣泛運用于安卓開發之中的一種軟件架構模式,而事件總線模式在安卓開發中最廣泛的應用莫過于AndroidStudio提供的EventBus,所以我就EventBus來談談對事件總線模式的認識。
EventBus是Android下高效的發布/訂閱事件總線機制。作用是可以代替傳統的Intent,Handler,Broadcast或接口函數在Fragment,Activity,Service,線程之間傳遞數據,執行方法。特點是代碼簡潔,是一種發布訂閱設計模式(Publish/Subsribe),或稱作觀察者設計模式。我們可能對事物總線機制還是有點陌生,但是想必對23種軟件設計模式之后的觀察者模式應該很熟悉。事物總線模式就是觀察者設計模式的一種,它的工作部件主要分為四種:事件源、事件監聽器、通道和事件總線。它的主要工作原理:事件源將產生的消息發送到事件總線的特定通道之上,然后監聽器在事先會訂閱事務總線之中不同的通道以區分消息的響應,然后當消息被發送到事務總線的特定通道之中時,所對應的監聽器會監聽到消息,然后監聽器根據程序中設置的響應函數進行執行。就好像一個Activity之中設置的Button一樣,在xml文件中放入一個Button,然后在java類中設定OnEvent()函數,當Button被點擊的時候,則會傳出一個點擊消息,然后按鈕對應的Onclick()函數,監聽到點擊消息,從而執行OnListerner()之中的函數。
那么下面我們結合具體的實例來分析事件總線模式,提到這個模式我們第一個想到的一定是Adroid開發之中的一個組件——Event Bus。Event Bus是Android Studio官方為我們提供的一個工具包。下面我們就根據一個具體的框架來對Event Bus進行講解。
我們想要實現的一個效果是,有兩個acivity如圖MainActivity:當點擊"click"按鈕的時候,就會跳轉到secondActivity,而secondActivity里面有兩個按鈕,點擊以后,可以改變MainActivity里面TextView的文字。
要實現這樣的效果無非是完成一個消息的傳遞,相當于我們的觀察者模式中發布者發布的一個消息,然后訂閱者通過特定的通道進行監聽,最后實現消息的傳遞。
首先是MainActivity:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public?class?MainActivity?extends?FragmentActivity {? ????Button btn;? ????TextView text;? ????@Override ????protected?void?onCreate(Bundle savedInstanceState) {? ????????super.onCreate(savedInstanceState);? ????????setContentView(R.layout.activity_main);? ????????EventBus.getInstance().register(this);? ????????btn = (Button) findViewById(R.id.btn);? ????????text = (TextView) findViewById(R.id.text);? ????????btn.setOnClickListener(new?View.OnClickListener() {? ????????????@Override ????????????public?void?onClick(View v) {? ????????????????startActivity(new?Intent(MainActivity.this,SecondActivity.class));? ????????????}? ????????});? ????}? ????public?void?onEvent(Info i){? ????????Log.i("cky", i.msg);? ????}? ????public?void?onEventMain(Info i){? ????????text.setText(i.msg);? ????}? ????public?void?onEventMain(Info2 i){? ????????text.setText(text.getText()+i.msg);? ????}? } |
從上面我們可以看出MainActivity的創建函數onCreate函數中調用了EventBus的register(this)函數,用來注冊。然后是onEvent(),這個方法里面的代碼,會在一個子線程中執行一個是onEventMain(),這個方法里面的代碼,會在UI線程執行。
然后是SecondActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public?class?SecondActivity?extends?Activity {? ????Button btn2;? ????Button btn3;? ????@Override ????protected?void?onCreate(Bundle savedInstanceState) {? ????????super.onCreate(savedInstanceState);? ????????setContentView(R.layout.activity_second);? ????????btn2 = (Button) findViewById(R.id.btn2);? ????????btn2.setOnClickListener(new?View.OnClickListener() {? ????????????@Override ????????????public?void?onClick(View v) {? ????????????????EventBus.getInstance().post(new?Info("信息1"));? ????????????}? ????????});? ????????btn3 = (Button) findViewById(R.id.btn3);? ????????btn3.setOnClickListener(new?View.OnClickListener() {? ????????????@Override ????????????public?void?onClick(View v) {? ????????????????EventBus.getInstance().post(new?Info2("信息2"));? ????????????}? ????????});? ????}? } |
那么這些活動之中的“始作俑者”——EventBus類又是什么樣的呢?
1 2 3 4 5 6 7 8 9 10 11 12 |
public?class?EventBus {? ????HashMap ????????????new?HashMap ????MainThreadHandler mainThreadHandler =?new?MainThreadHandler(this,Looper.getMainLooper());? ????AsyThreadHandler asyThreadHandler =?new?AsyThreadHandler(this);? ????private?final?static?EventBus instance =?new?EventBus();? ????public?static?EventBus getInstance(){? ???????????return?instance;? ????}? ????private?EventBus(){};? } |
在這其中:
register方法之中我們先獲取了訂閱者(例子中是MainActivity)的方法,找到onEvent開頭的方法,獲得它們的參數類型。然后判斷subscriptionsByEventType是否有以這些參數類型為key的數據,如果沒有,新建一個ArrayList
Subscription它代表一個訂閱,擁有subsriber,也就是訂閱者還有一個SubscriberMethod,這是訂閱方法類。
post()方法里面,如同我們上面所說,獲取了參數類型,然后在subscriptionsByEventType中查詢所有改類型對應的訂閱Subscription對于Subscription,它有我們訂閱類的所有信息。首先根據type判斷是在主線程還是子線程執行,然后調用一開始講到的兩個類的實例就好了。
invoke()其實只有一句話,就是調用了反射去執行方法。m是訂閱方法,sub.subscriber就是訂閱者,event就是post()方法傳入的實體這樣我們就在子線程中調用了這個方法了,相當于MainActivity主動調用這個方法。
因為這個模式的使用較少所以網上可以找到的只有這一種實例,其實事件總線這個概念對你來說可能很陌生,但提到觀察者(發布-訂閱)模式,你也許就很熟悉。事件總線是對發布-訂閱模式的一種實現。它是一種集中式事件處理機制,允許不同的組件之間進行彼此通信而又不需要相互依賴,達到一種解耦的目的。
評論
查看更多