分析EventBus是如何發(fā)送事件的趾疚,入口就是EventBus的post方法內(nèi)
以上代碼可以拆解以下幾個(gè)步驟:
1:從TheadLocal修飾的對(duì)象內(nèi)取出1個(gè)PostingTheadState,該對(duì)象保存了當(dāng)前線程的狀態(tài)
2:從PostTheadState對(duì)象內(nèi)取出當(dāng)前事件的隊(duì)列立膛,并將要發(fā)送的事件添加到隊(duì)列內(nèi)
3:檢查狀態(tài),循環(huán)從隊(duì)列中取出事件進(jìn)行發(fā)送
4:復(fù)位PostTheadState狀態(tài)
流程進(jìn)入postSingleEvent方法內(nèi)讹堤,接著往下看
該流程也可拆分以下步驟:
1:查找跟要發(fā)送的事件相關(guān)的類以及接口吆鹤,存儲(chǔ)在緩存中
2:依次發(fā)送事件
3:如果無訂閱方法,發(fā)送1個(gè)默認(rèn)事件
方法主要還是進(jìn)入postSingleEventForEventType內(nèi)洲守;
繼續(xù)拆分:
1:通過要發(fā)送的事件查詢他的全部訂閱者信息
2:循環(huán)遍歷每個(gè)訂閱者疑务,執(zhí)行postToSubscription
3:修改PostingThreadState狀態(tài)信息
進(jìn)入postToSubscription
該方法是發(fā)送事件的重點(diǎn),前面的操作為事件的發(fā)送進(jìn)行鋪墊梗醇;
講到該方法知允,就得了解下TheadMode這個(gè)對(duì)象了,它是EventBus中的1個(gè)枚舉類叙谨,包含以下五種狀態(tài)
POSTING 默認(rèn)訂閱者和發(fā)布者同個(gè)線程
MAIN 主線程訂閱
MAIN_ORDERED 主線程訂閱
BACKGROUND, 后臺(tái)訂閱
ASYNC 異步訂閱
TheadMode的設(shè)置就決定了該訂閱方法在哪個(gè)線程被調(diào)度温鸽。
1:POSTING方式 ,直接調(diào)用invokeSubscriber反射調(diào)用觸發(fā)訂閱方法
2:MAIN方式手负,判斷發(fā)布者所在線程涤垫,如果是在主線程則直接調(diào)用invokeSubscriber反射調(diào)用觸發(fā)訂閱方法,否則通過mainThreadPoster調(diào)度來觸發(fā)
后面3,4,5原理邏輯 基本一致竟终,只是Poster不一樣蝠猬;
逐個(gè)分析下不同的Poster;
EventBus的成員變量就有3個(gè)不同的Poster, 并且在EventBus初始化的時(shí)候就初始化了
MainThreadPoster最終創(chuàng)建的是HandlerPoster
分發(fā)的時(shí)候執(zhí)行的是mainThreadPoster.enqueue,
在PendingPost中取出1個(gè)事件添加到隊(duì)列中衡楞,sendMessage觸發(fā)Handler的handlerMessage方法
handleMessage會(huì)開始1個(gè)死循環(huán)吱雏,不斷的從隊(duì)列中取出Post事件來執(zhí)行敦姻,取出事件后反射調(diào)用觸發(fā)訂閱方法瘾境;
循環(huán)退出的條件:1隊(duì)列中無post事件,2超過最大事件限制
BackgroundPoster實(shí)現(xiàn)的是Runnable接口 是一個(gè)線程類
enqueue也是從PendingPost中取出1個(gè)PendingPost放入隊(duì)列中镰惦,調(diào)用線程池開啟線程迷守,回調(diào)到run方法,接著看run方法
run方法內(nèi)也是1個(gè)死循環(huán)旺入,不斷的從隊(duì)列內(nèi)取出Post事件進(jìn)行處理兑凿,取出事件后調(diào)用invoke方法反射調(diào)用觸發(fā)訂閱方法;
AsyncPoster
AsyncPoster實(shí)現(xiàn)的也是Runnable接口茵瘾,但是run方法只取出1個(gè)進(jìn)行分發(fā)礼华,因?yàn)槊看味际怯嗛喌亩际窃?個(gè)新的線程,不會(huì)出現(xiàn)互相卡頓的現(xiàn)象拗秘;