執(zhí)行的線程呻引,優(yōu)先級,是否是粘性時間 @Subscribe(threadMode = ThreadMode.MAIN,priority = 100,sticky = true)
1 注冊:
EventBus.Register(this);
2解綁:
EventBus.unRegister(this);
3接收
@Subscribe
public void func(eventBean event) {}
4發(fā)送
EventBus.post
register(obj) :
遍歷傳入的 class的所有方法枉长,找到有Subscribe注解的所有方法 返回一個list
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);?
}
}
}
findUsingReflectionInSingleClass 第一步:解析注冊者對象的所有方法玉转,并且找出帶有注解subscribe注解的方法荚板,然后通過annotation解析所有細(xì)節(jié)參數(shù)址遇, 封裝成一個對象,添加到集合滋戳,返回钻蔑。
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
先從緩存中取
如果緩存中沒有
ignoreGeneratedIndex:是否忽略注解生成器的MyEventBusIndex 默認(rèn)false
默認(rèn)走注解生成器
如果獲取的列表為空,拋出異常
否則 返回list
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
subscriberMethods = findUsingInfo(subscriberClass);
}
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass
+ " and its super classes have no public methods with the @Subscribe annotation");
} else {
METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods;
}
}
findUsingReflectionInSingleClass 核心方法
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// This is faster than getMethods, especially when subscribers are fat classes like Activities
methods = findState.clazz.getDeclaredMethods(); //獲取所有方法
} catch (Throwable th) {
// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
for (Method method : methods) {
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
ThreadMode threadMode = subscribeAnnotation.threadMode();
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException("@Subscribe method " + methodName +
"must have exactly 1 parameter but has " + parameterTypes.length);
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException(methodName +
" is a illegal @Subscribe method: must be public, non-static, and non-abstract");
}
}
}
private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);
findState.recycle();
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
if (FIND_STATE_POOL[i] == null) {
FIND_STATE_POOL[i] = findState;
break;
}
}
}
return subscriberMethods;
}
最終裝入緩存池奸鸯,并返回對象
//— .method.getParameterTypes 獲取參數(shù)列表
//method.setAccessible(true); 似有方法需要執(zhí)行這句
Class a = Client.class;
try {
Method method = a.getDeclaredMethod("a", int.class, int.class);
System.out.println("----"+method.getParameterTypes().length + "-------“);//2
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
第二步:
subscribe() 解析所有SubscriberMethod的eventType,然后按照要求解析成
Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType的格式咪笑,
key是eventType
value就是subscription的列表,subscription包含兩個對象的封裝
如下
final class Subscription {
final Object subscriber;//
final SubscriberMethod subscriberMethod;//
娄涩。窗怒。。
}
所以最終形成的map結(jié)構(gòu)是這樣:
@Subscribe
public void onRefresh(EventB event) {
}
/*
subscriptionsByEventType 的key 就是 EventB.class
Subscription 中的參數(shù)分別對應(yīng)的 方法依托的類 蓄拣,以及具體的方法
*/
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//eventType是方法參數(shù)的class
Class<?> eventType = subscriberMethod.eventType;
//再次封裝對象扬虚,一個Subscription,對象中存入 :eg:activity實例弯蚜,第二個是解析好的被注解的那個方法
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//subscriptionsByEventType
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);//一個map key:對應(yīng)的類 a
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
if (subscriberMethod.sticky) {
if (eventInheritance) {
// Existing sticky events of all subclasses of eventType have to be considered.
// Note: Iterating over all events may be inefficient with lots of sticky events,
// thus data structure should be changed to allow a more efficient lookup
// (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
post源碼分析:待續(xù)