項(xiàng)目上線有一段時(shí)間了,自己總結(jié)了下項(xiàng)目牡彻。項(xiàng)目中的EventBus
真的是到處都有它的影子,說實(shí)話缎除,用上EventBus
后总寻,個(gè)人覺得項(xiàng)目中的業(yè)務(wù)變得很輕松渐行,不用考慮哪個(gè)類發(fā)的,哪個(gè)類去回調(diào)肴沫。別人都說EventBus
是一個(gè)"事務(wù)總線",就像一個(gè)公司的項(xiàng)目小組一樣颤芬。項(xiàng)目經(jīng)理給各個(gè)模塊的分配好任務(wù)了,然后各人模塊的人員處理自己的事情夺艰,最后完成整個(gè)事務(wù)。
Bus類:
public class Bus {
static volatile Bus sInstance;
Finder mFinder;
//CopyOnWriteArrayList一般用在讀和寫同時(shí)存在的情況下使用
Map<Class<?>, CopyOnWriteArrayList<Subscriber>> mSubscriberMap;
PostHandler mPostHandler;
private Bus() {
mFinder = new NameBasedFinder();
mSubscriberMap = new HashMap<>();
mPostHandler = new PostHandler(Looper.getMainLooper(), this);
}
/**
* 得到一個(gè)單例的上下文對(duì)象
* @return
*/
public static Bus getDefault() {
if (sInstance == null) {
synchronized (Bus.class) {
if (sInstance == null) {
sInstance = new Bus();
}
}
}
return sInstance;
}
public void register(Object subscriber) {
/**
* 找到該類下面的所有以onEvent開頭的方法
*/
List<Method> methods = mFinder.findSubscriber(subscriber.getClass());
if (methods == null || methods.size() < 1) {
return;
}
CopyOnWriteArrayList<Subscriber> subscribers = mSubscriberMap.get(subscriber.getClass());
if (subscribers == null) {
subscribers = new CopyOnWriteArrayList<>();
/**
* 該map用來存儲(chǔ)onevent開頭的方法的第一個(gè)參數(shù)為key和
* subscribers的集合
*/
mSubscriberMap.put(methods.get(0).getParameterTypes()[0], subscribers);
}
for (Method method : methods) {
/**
* 封裝了該類和該類帶有onevent的方法
*/
Subscriber newSubscriber = new Subscriber(subscriber, method);
subscribers.add(newSubscriber);
}
}
public void unregister(Object subscriber) {
CopyOnWriteArrayList<Subscriber> subscribers = mSubscriberMap.remove(subscriber.getClass());
if (subscribers != null) {
for (Subscriber s : subscribers) {
s.mMethod = null;
s.mSubscriber = null;
}
}
}
public void post(Object event) {
//TODO post with handler
mPostHandler.enqueue(event);
}
}
Bus
類主要是消息的注冊(cè)存谎、發(fā)送既荚、注銷幾個(gè)動(dòng)作。
在注冊(cè)中句各,首先找到要注冊(cè)類中onEvent
方法晴叨,這里是怎么做到的呢。大家找找成員變量mFinder
是怎么生成的。其實(shí)它是一個(gè)接口:
public interface Finder {
List<Method> findSubscriber(Class<?> subscriber);
}
再來看看它的實(shí)現(xiàn)類吧:
public class NameBasedFinder implements Finder {
/**
* public Method[] getMethods()返回某個(gè)類的所有公用(public)方法包括其繼承類的公用方法胚宦,當(dāng)然也包括它所實(shí)現(xiàn)接口的方法浓体。
public Method[] getDeclaredMethods()返回自身類的所有公用(public)方法包括私有(private)方法,但包括其繼承類的方法油吭,當(dāng)然也包括它所實(shí)現(xiàn)接口的方法纽绍。
* 找到某個(gè)類的所有的
* @param subscriber
* @return
*/
@Override
public List<Method> findSubscriber(Class<?> subscriber) {
List<Method> methods = new ArrayList<>();
for (Method method : subscriber.getDeclaredMethods()) {
if (method.getName().startsWith("onEvent") &&
method.getParameterTypes().length == 1) {
methods.add(method);
}
}
return methods;
}
}
看到了沒拌夏,該實(shí)現(xiàn)類只是簡(jiǎn)單地將onEvent
開頭的方法給封裝到一個(gè)集合里面去了障簿。
接著看注冊(cè)里面栅迄,獲取到以onEvent
開頭的方法后毅舆,將該method集合添加到一個(gè)mSubscriberMap
中,該map中的key就是onEvent
開頭的方法的第一個(gè)參數(shù)岂津,value就是Subscriber的集合吮成。
那就再來看看Subscriber
類吧:
public class Subscriber {
Object mSubscriber;
Method mMethod;
Class<?> mEventType;
public Subscriber(Object subscriber, Method method) {
mSubscriber = subscriber;
mMethod = method;
mEventType = method.getParameterTypes()[0];
}
}
該類有三個(gè)成員變量粱甫,可能現(xiàn)在有人不知道為啥要這么定義作瞄,到了后面用到的時(shí)候就知道為啥這么定義了宗挥。
好了,整個(gè)注冊(cè)的過程就這樣安拟,最終的目的就是得到一個(gè)map對(duì)象糠赦。
下面來看看發(fā)送的過程吧:
mPostHandler.enqueue(event);
就這一行代碼拙泽,下面就看看mPostHandler
類是怎么得來的吧顾瞻。
mPostHandler = new PostHandler(Looper.getMainLooper(), this);
下面來看看PostHandler類吧:
public class PostHandler extends Handler {
final Bus mBus;
public PostHandler(Looper looper, Bus bus) {
super(looper);
mBus = bus;
}
@Override
public void handleMessage(Message msg) {
CopyOnWriteArrayList<Subscriber> subscribers = mBus.mSubscriberMap.get(msg.obj.getClass());
for (Subscriber subscriber : subscribers) {
subscriber.mMethod.setAccessible(true);
try {
/**
* 第二個(gè)參數(shù)是方法的參數(shù)荷荤,第-個(gè)參數(shù)是該類的對(duì)象
*/
subscriber.mMethod.invoke(subscriber.mSubscriber, msg.obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
void enqueue(Object event) {
Message message = obtainMessage();
message.obj = event;
sendMessage(message);
}
}
看到該類了沒蕴纳,還是逃不過handler通過handleMessage方法來接收處理消息了,這個(gè)地方就是核心的地方了翻翩。這里實(shí)際上bus類的post方法的參數(shù)就是這里的bus類中mSubscriberMap
的key了嫂冻,通過該key可以獲取到mSubscriberMap
中的value值了塞椎,也就是Subscriber集合了,現(xiàn)在知道Subscriber類的定義了吧蹬敲,mMethod
是方法名,mSubscriber
是該類對(duì)象急波,實(shí)際上它的第三個(gè)成員變量沒用到澄暮。最后通過反射來調(diào)用onEvent
開頭的方法,整個(gè)過程就這么簡(jiǎn)單伸辟,是不是現(xiàn)在一目了然了呢信夫。
最后就是注銷了:
public void unregister(Object subscriber) {
CopyOnWriteArrayList<Subscriber> subscribers = mSubscriberMap.remove(subscriber.getClass());
if (subscribers != null) {
for (Subscriber s : subscribers) {
s.mMethod = null;
s.mSubscriber = null;
}
}
}
這里沒什么好說的吧警没,就是將map中的對(duì)象給至空了杀迹。
好了树酪,整個(gè)過程就這樣了嗅回,是不是幾個(gè)過程都清楚了绵载。
下面用一個(gè)demo來測(cè)試該事例吧:
整個(gè)的內(nèi)容就這么多了娃豹,完全是靠自己的理解懂版。如果有什么說得不清楚的地方躯畴,還需大家指出來蓬抄。
借鑒的項(xiàng)目:https://github.com/avenwu/support
關(guān)于我:
email:a1002326270@163.com
github:enter