由於我們專案使用了eventbus2,所以檢視一下原始碼,了解一下原理關鍵的event快取資料結構
// 訂閱方法,按event型別歸類
private
final map, copyonwritearraylist> subscriptionsbyeventtype;
// 快取已經註冊的物件,可防止物件重複註冊
private
final map>> typesbysubscriber;
// 快取粘性時間,用於使用registersticky方法註冊後立刻執行事件
private
final map, object> stickyevents;
註冊方法
private
synchronized
void
register(classloader loader, string stuckclassname, object subscriber, string methodname, boolean sticky, int priority)
listsubscribermethods = subscribermethodfinder.findsubscribermethods(loader, stuckclassname, subscriber.getclass(),
methodname);
for (subscribermethod subscribermethod : subscribermethods)
}public
synchronized
boolean
isregistered(object subscriber)
查詢方法
listfindsubscribermethods(classloader loader, string stuckclassname, class<?> subscriberclass, string eventmethodname)
if (subscribermethods != null)
subscribermethods = new arraylist();
class<?> clazz = loadclass(loader, subscriberclass);
hashset eventtypesfound = new hashset();
stringbuilder methodkeybuilder = new stringbuilder();
while (clazz != null)
// starting with eventbus 2.2 we enforced methods to be public (might change with annotations again)
method methods = clazz.getdeclaredmethods();
for (method method : methods) else
if (modifierstring.equals("mainthread")) else
if (modifierstring.equals("backgroundthread")) else
if (modifierstring.equals("async")) else else
}class<?> eventtype = parametertypes[0];
methodkeybuilder.setlength(0);
//拼接key,方法名字+">"+引數類名
string methodkey = methodkeybuilder.tostring();
if (eventtypesfound.add(methodkey))
}} else
if (!skipmethodverificationforclasses.containskey(clazz)) }}
//對比查詢類名,相同跳出方法
if (name.equals(stuckclassname))
//搜尋父類的方法
clazz = loadclass(loader, clazz.getsuperclass());
}if (subscribermethods.isempty()) else
return subscribermethods;
}}
訂閱監聽者
// must be called in synchronized block
private
void
subscribe(object subscriber, subscribermethod subscribermethod, boolean sticky, int priority) else }}
// starting with eventbus 2.2 we enforced methods to be public (might change with annotations again)
// subscribermethod.method.setaccessible(true);
int size = subscriptions.size();
for (int i = 0; i <= size; i++)
}list> subscribedevents = typesbysubscriber.get(subscriber);
if (subscribedevents == null)
subscribedevents.add(eventtype);
//執行粘性事件
if (sticky)
if (stickyevent != null)
}}
傳送事件
public
void
post(object event) else
try
} finally }}
//獲取event監聽者,分發事件
private
void
postsingleevent(object event, postingthreadstate postingstate) throws error
if (subscriptions != null && !subscriptions.isempty()) finally
if (aborted)
}subscriptionfound = true;}}
if (!subscriptionfound) }}
// 執行訂閱的方法
private
void
posttosubscription(subscription subscription, object event, boolean ismainthread) else
break;
case threadmode.backgroundthread:
if (ismainthread) else
break;
case threadmode.async:
//static executorservice executorservice = executors.newfixedthreadpool(15);
// 非同步併發方法,通過固定執行緒池切換到子執行緒執行,最多可以執行15個任務
asyncposter.enqueue(subscription, event);
break;
default:
throw
new illegalstateexception("unknown thread mode: " + subscription.subscribermethod.threadmode);
}}
傳送粘性事件,先快取event,在上面訂閱時將執行方法
public
void
poststicky(object event)
post(event);
}
取消粘性事件,將事件在快取中移除
public boolean removestickyevent(object event) else }}
反註冊方法
public synchronized void
unregister(object subscriber)
//移除註冊的物件
typesbysubscriber.remove(subscriber);
} else
private
void
unubscribebyeventtype(object subscriber, class<?> eventtype) }}
}
EventBus分析原始碼
public static eventbus getdefault return defaultinstance 這裡是註冊訂閱者的地方,同樣的註冊方式有這麼 它們之間最主要的區別就是引數的不同。在實現上它們都是呼叫void register object subscriber,boolean st...
EventBus原始碼分析
前言 eventbus在現如今android專案中用來進行通訊使用很廣泛。在本篇文章中,我將會分為下面幾個模組來講解eventbus 如何使用,原始碼分析,使用注意事項,高階技能。除了上面說的幾個exception,如果我們重複呼叫register的話,會出現throw new eventbu ce...
EventBus 簡單原始碼 原理分析
1.初始化 eventbus.getdefatult 單例模式初始化。public static eventbus getdefault return instance 傳入乙個預設builder 進行初始化 public eventbus eventbus eventbusbuilder buil...