EventBus設計原理 流程分析

2021-09-21 13:52:47 字數 4690 閱讀 5691

本篇不涉及任何原始碼,單純講一下它的流程,然後講一下優缺點。

eventbus 中有三個集合,這基本就是核心所在。

private final map, copyonwritearraylist> subscriptionsbyeventtype;

//第乙個集合的儲存的

//key是資料型別的clazz 

//value 是乙個subscription集合,

//subscription物件是乙個包裝類,包含註冊的時候傳進去的物件 和物件中乙個帶 @subscribe 註解的方法,

很抽象 舉例演示一下 

public class a

@subscribe (threadmode = threadmode.main)

public void accept2(person p)

}public class b

@subscribe (threadmode = threadmode.main)

public void accept4(person p)

}public class c

@subscribe (threadmode = threadmode.main)

public void accept2(student s)

}1,當 a 類呼叫  eventbus.getdefault().register(this);進行註冊之後 ,

subscriptionsbyeventtype集合長度為 1,第乙個key是 person.class ,value 就是乙個長度為2的copyonwritearraylist物件,copyonwritearraylist中

第乙個subscription 是a物件的例項和 a物件的 accept1方法封裝成的 subscription 物件,

第二個subscription 是a物件的例項和 a物件的 accept2方法封裝成的 subscription  物件

2,當b類物件呼叫 eventbus.getdefault().register(this);進行註冊之後 ,

subscriptionsbyeventtype集合長度為 1,第乙個key是person.class ,value 就是乙個長度為4的copyonwritearraylist物件,copyonwritearraylist中

第乙個subscription 是a物件的例項和 a物件的 accept1方法封裝成的 subscription 物件,

第二個subscription 是a物件的例項和 a物件的 accept2方法封裝成的 subscription 物件,

第三個subscription 是b物件的例項和 b物件的 accept3方法封裝成的 subscription  物件,

第四個subscription 是b物件的例項和 b物件的 accept4方法封裝成的 subscription  物件,

3,當c類物件呼叫 eventbus.getdefault().register(this);進行註冊之後 ,

subscriptionsbyeventtype集合長度為 2,

第乙個key是 person.class ,第乙個key對應的value 就是乙個長度為4的copyonwritearraylist物件,

第乙個copyonwritearraylist物件中的四個物件《步驟2中的四個subscription 》

第二個key是 student.class, 第二個key對應的value 是乙個長度為 2的 copyonwritearraylist物件,

第二個copyonwritearraylist物件中的兩個個物件

第乙個subscription 是c物件的例項和 c物件的 accept1方法封裝成的 subscription 物件,

第乙個subscription 是c物件的例項和 c物件的 accept2方法封裝成的 subscription 物件,

在總結一下 ,

1,所有訂閱的方法中,有多少引數型別,subscriptionsbyeventtype 的長度就是多少,每個引數型別 對應乙個list集合。

2,該引數型別有多少個訂閱的方法 ,對應的list集合長度就是多少,每乙個subscription  物件都是訂閱的方法和方法所在的類的 例項。

這個集合的作用就是用來 分發事件用的,當發事件的時候,根據分發的事件型別的clazz ,拿到對應訂閱的方法的集合copyonwritearraylist物件,然後逐一遍歷進行分發,這也就是分發的原理。當然真正的流程沒有這麼簡單,還涉及到了執行緒切換等等,這裡不細說,主要介紹主流程。

偽**public void register (object subscriber) else }}

}第二個集合

private final map>> typesbysubscriber;

//這個集合的作用主要解除註冊用的 ,

//key是註冊時候的tag

//vlaue 的值是乙個引數型別clazz集合。

當有類進行註冊的時候,對第乙個集合進行操作的同時,也會對第二個集合進行操作,(上邊的流程)

1,當 a 類呼叫  eventbus.getdefault().register(this);進行註冊之後 ,

typesbysubscriber集合長度為 1,第乙個key是a物件 ,value 就是乙個長度為2的list物件,

第乙個class是person.class,

第二個class是person.class,

2,當b類物件呼叫 eventbus.getdefault().register(this);進行註冊之後 ,

typesbysubscriber集合長度為 2,

第乙個key是a物件 ,value 就是乙個長度為2的list物件,

《步驟一中的list 》

第二個key是b物件,vlaue 就是乙個長度為2的list物件,

第乙個class是person.class,

第二個class是person.class,

3,當c類物件呼叫 eventbus.getdefault().register(this);進行註冊之後 ,

typesbysubscriber集合長度為 3,

第乙個key是a物件 ,value 就是乙個長度為2的list物件,

《步驟一中的list 》

第二個key是b物件,vlaue 就是乙個長度為2的list物件,

《步驟二中的list 》

第三個key 是c物件,value 就是乙個長度為2的list物件,

第乙個class是student.class,

第二個class是student.class,

在總結一下 ,

1,有多少個物件訂閱了,typesbysubscriber的長度就是多少,每個訂閱物件對應乙個list集合。

2,每個訂閱的物件中有多少個訂閱的方法,list的長度就是多少,原始碼就是遍歷所有訂閱的方法,list把每個方法的引數新增進去。

這個集合主要的作用是用來解除註冊的,

解除註冊的時候,首先拿到要解除註冊物件的所有方法的引數class的集合,然後遍歷這個class集合,遍歷的時候 通過第乙個集合拿到每乙個class所有的訂閱方法,這裡拿到的也是乙個集合copyonwritearraylist,在遍歷這個集合,凡是subscription中 持有的物件 和當前要解除的物件一樣的情況下,就把當前subscription物件 從copyonwritearraylist當中移除。遍歷完所有list集合之後就成功的解除了當前物件所有的訂閱,最後從typesbysubscriber 把 當前物件保留的集合移除

偽**public synchronized void unregister(object tag) }}

}typesbysubscriber.remove(subscriber);}}

第三個集合的作用 作為粘性分發的作用

private final map, object> stickyevents;

//第三個集合是粘性分發

//key是資料型別的clazz 

//value 是資料物件,

現在說事件分發 只介紹兩種正常分發 和粘性分發

第一種,正常分發

直接上偽**

public void post(object event) }}

這就是正常分發流程。

第二種粘性分發,粘性分發的就是先分發,後註冊也能收到訊息,原理就在此,正常分發,然後把資料存起來。

1,粘性分發首先執行一邊上邊正常的流程。

2,利用第三個集合 把分發的資料儲存起來

再講前邊註冊的流程中 最後一步,

偽**public void register(object  tag)

}最後簡單串聯一下邏輯:

註冊的時候

1把當前物件所有註冊方法放到第乙個集合當中管理,為了分發 用。

2同事第二個集合儲存的資料就是記錄了那些物件註冊了,用來解除註冊。 

3如果是粘性事件 去第三個集合中尋找對應的資料型別和資料,然後直接進行分發。

傳送事件的時候

1根據傳送的事件型別找到所有需要傳送物件的對應方法

解除註冊的時候,

1通過第二個集合找到所有註冊的方法,然後進行逐個判斷進行解除註冊。

最後說一下個人所認為的優缺點 

優點 :可以跨模組傳送訊息。原理就是動態註冊動態傳送

缺點 : 接受事件型別

1事件型別會定義很多

2不同模組的訊息型別必須兩個模組都能引用到才行

3不是流程式的**,閱讀性差。個人傾向於流程式的**。

事件匯流排 EventBus的設計原理

為什麼要設計eventbus?因為他是領域驅動設計中比不可少的模組,它承擔傳輸資料的作用,它可以解耦模組之間的耦合性。如何對eventsbus進行定義 1 eventbus是基於jvm內部的資料傳輸系統,不是jms。2 eventbus的核心物件為event和eventhandler。eventbu...

EventBus原理詳解

在eventbus 3.0 使用介紹 這篇部落格中介紹了關於eventbus的一些使用方法,下面我們就來看看它內部的具體實現吧!通過上面的幾張圖,我們可以大致了解eventbus的工作流程,下面我們在來介紹一下這個流程中比較重要的幾個方法 listfindsubscribermethods clas...

EventBus二之反射原理

目錄 1 新建android libray 2 定義eventbus反射機制需要的元素 3 實現eventbus核心類 新建android libray 定義eventbus反射機制需要的元素 a.新增註解類 target elementtype.method retention retention...