执行的线程,优先级,是否是粘性时间 @Subscribe(threadMode = ThreadMode.MAIN,priority = 100,sticky = true)
1 注册:
EventBus.Register(this);
2解绑:
EventBus.unRegister(this);
3接收
@Subscribe
public void func(eventBean event) {}
4发送
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解析所有细节参数, 封装成一个对象,添加到集合,返回。
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
先从缓存中取
如果缓存中没有
ignoreGeneratedIndex:是否忽略注解生成器的MyEventBusIndex 默认false
默认走注解生成器
如果获取的列表为空,抛出异常
否则 返回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 获取参数列表
//method.setAccessible(true); 似有方法需要执行这句
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结构是这样:
@Subscribe
public void onRefresh(EventB event) {
}
/*
subscriptionsByEventType 的key 就是 EventB.class
Subscription 中的参数分别对应的 方法依托的类 ,以及具体的方法
*/
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//eventType是方法参数的class
Class<?> eventType = subscriberMethod.eventType;
//再次封装对象,一个Subscription,对象中存入 :eg:activity实例,第二个是解析好的被注解的那个方法
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//subscriptionsByEventType
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);//一个map key:对应的类 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源码分析:待续
网友评论