tips:
- 接口的使用
public interface ThreadEnforcer {
ThreadEnforcer ANY = new ThreadEnforcer() {
public void enforce(Bus bus) {
}
};
ThreadEnforcer MAIN = new ThreadEnforcer() {
public void enforce(Bus bus) {
if(Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("Event bus " + bus + " accessed from non-main thread " + Looper.myLooper());
}
}
};
void enforce(Bus var1);
}
- 判断是否为主线程:
if(Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("Event bus " + bus + " accessed from non-main thread " + Looper.myLooper());
}
- 主要是Bus.java里面的代码:
关键的方法有
public void register(Object object)
该方法的作用是查找object里面所有带有Produce和Subscribe注解的方法,并保存在Map中,并且会立即执行Produce注解的方法。
private static void loadAnnotatedMethods(Class<?> listenerClass) {
HashMap subscriberMethods = new HashMap();
HashMap producerMethods = new HashMap();
Method[] arr$ = listenerClass.getDeclaredMethods();//将所有的方法都取出来
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; ++i$) {
Method method = arr$[i$];
Class[] parameterTypes;
Class eventType;
if(method.isAnnotationPresent(Subscribe.class)) { //自定义注解获取方法
parameterTypes = method.getParameterTypes();
if(parameterTypes.length != 1) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation but requires " + parameterTypes.length + " arguments. Methods must require a single argument.");
}
eventType = parameterTypes[0];
if(eventType.isInterface()) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType + " which is an interface. Subscription must be on a concrete class type.");
}
if((method.getModifiers() & 1) == 0) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType + " but is not \'public\'.");
}
Object methods = (Set)subscriberMethods.get(eventType);
if(methods == null) {
methods = new HashSet();
subscriberMethods.put(eventType, methods);
}
((Set)methods).add(method);
} else if(method.isAnnotationPresent(Produce.class)) {
parameterTypes = method.getParameterTypes();
if(parameterTypes.length != 0) {
throw new IllegalArgumentException("Method " + method + "has @Produce annotation but requires " + parameterTypes.length + " arguments. Methods must require zero arguments.");
}
if(method.getReturnType() == Void.class) {
throw new IllegalArgumentException("Method " + method + " has a return type of void. Must declare a non-void type.");
}
eventType = method.getReturnType();
if(eventType.isInterface()) {
throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType + " which is an interface. Producers must return a concrete class type.");
}
if((method.getModifiers() & 1) == 0) {
throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType + " but is not \'public\'.");
}
if(producerMethods.containsKey(eventType)) {
throw new IllegalArgumentException("Producer for type " + eventType + " has already been registered.");
}
producerMethods.put(eventType, method);
}
}
PRODUCERS_CACHE.put(listenerClass, producerMethods); //将所有带有Subscribe.class gen跟Produce.class 注解的方法保存下来
SUBSCRIBERS_CACHE.put(listenerClass, subscriberMethods);
}
- public void post(Object event)
发送事件event,根据之前注册过的object里面的方法,查找参数为event的Subscribe方法,并invoke该方法。这样就达到了post之后,调用对应Subscribe方法的目的。
EventHandler(Object target, Method method) {
if(target == null) {
throw new NullPointerException("EventHandler target cannot be null.");
} else if(method == null) {
throw new NullPointerException("EventHandler method cannot be null.");
} else {
this.target = target;
this.method = method;
method.setAccessible(true); //注意此处的开关是关闭java的安全检查机制,能提高反射的性能
boolean prime = true;
this.hashCode = (31 + method.hashCode()) * 31 + target.hashCode();
}
}
public void handleEvent(Object event) throws InvocationTargetException {
try {
this.method.invoke(this.target, new Object[]{event});
} catch (IllegalAccessException var3) {
throw new AssertionError(var3);
} catch (InvocationTargetException var4) {
if(var4.getCause() instanceof Error) {
throw (Error)var4.getCause();
} else {
throw var4;
}
}
}
- public void unregister(Object object)
注销object,删除掉map中保存的object的方法,释放object,防止内存泄露。
总结:otto将所有带有注解的类存到map里面,包含了类,方法名,参数,等post或者有注解的时候,使用invoke 反射调用,所以都是使用了反射实现。
这里有一个小工具类,以后可以直接copy ,查找annotion
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.squareup.otto;
import com.squareup.otto.EventHandler;
import com.squareup.otto.EventProducer;
import com.squareup.otto.Produce;
import com.squareup.otto.Subscribe;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
final class AnnotatedHandlerFinder {
private static final Map<Class<?>, Map<Class<?>, Method>> PRODUCERS_CACHE = new HashMap();
private static final Map<Class<?>, Map<Class<?>, Set<Method>>> SUBSCRIBERS_CACHE = new HashMap();
private static void loadAnnotatedMethods(Class<?> listenerClass) {
HashMap subscriberMethods = new HashMap();
HashMap producerMethods = new HashMap();
Method[] arr$ = listenerClass.getDeclaredMethods();
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; ++i$) {
Method method = arr$[i$];
Class[] parameterTypes;
Class eventType;
if(method.isAnnotationPresent(Subscribe.class)) {
parameterTypes = method.getParameterTypes();
if(parameterTypes.length != 1) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation but requires " + parameterTypes.length + " arguments. Methods must require a single argument.");
}
eventType = parameterTypes[0];
if(eventType.isInterface()) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType + " which is an interface. Subscription must be on a concrete class type.");
}
if((method.getModifiers() & 1) == 0) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType + " but is not \'public\'.");
}
Object methods = (Set)subscriberMethods.get(eventType);
if(methods == null) {
methods = new HashSet();
subscriberMethods.put(eventType, methods);
}
((Set)methods).add(method);
} else if(method.isAnnotationPresent(Produce.class)) {
parameterTypes = method.getParameterTypes();
if(parameterTypes.length != 0) {
throw new IllegalArgumentException("Method " + method + "has @Produce annotation but requires " + parameterTypes.length + " arguments. Methods must require zero arguments.");
}
if(method.getReturnType() == Void.class) {
throw new IllegalArgumentException("Method " + method + " has a return type of void. Must declare a non-void type.");
}
eventType = method.getReturnType();
if(eventType.isInterface()) {
throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType + " which is an interface. Producers must return a concrete class type.");
}
if((method.getModifiers() & 1) == 0) {
throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType + " but is not \'public\'.");
}
if(producerMethods.containsKey(eventType)) {
throw new IllegalArgumentException("Producer for type " + eventType + " has already been registered.");
}
producerMethods.put(eventType, method);
}
}
PRODUCERS_CACHE.put(listenerClass, producerMethods);
SUBSCRIBERS_CACHE.put(listenerClass, subscriberMethods);
}
static Map<Class<?>, EventProducer> findAllProducers(Object listener) {
Class listenerClass = listener.getClass();
HashMap handlersInMethod = new HashMap();
if(!PRODUCERS_CACHE.containsKey(listenerClass)) {
loadAnnotatedMethods(listenerClass);
}
Map methods = (Map)PRODUCERS_CACHE.get(listenerClass);
if(!methods.isEmpty()) {
Iterator i$ = methods.entrySet().iterator();
while(i$.hasNext()) {
Entry e = (Entry)i$.next();
EventProducer producer = new EventProducer(listener, (Method)e.getValue());
handlersInMethod.put(e.getKey(), producer);
}
}
return handlersInMethod;
}
static Map<Class<?>, Set<EventHandler>> findAllSubscribers(Object listener) {
Class listenerClass = listener.getClass();
HashMap handlersInMethod = new HashMap();
if(!SUBSCRIBERS_CACHE.containsKey(listenerClass)) {
loadAnnotatedMethods(listenerClass);
}
Map methods = (Map)SUBSCRIBERS_CACHE.get(listenerClass);
if(!methods.isEmpty()) {
Iterator i$ = methods.entrySet().iterator();
while(i$.hasNext()) {
Entry e = (Entry)i$.next();
HashSet handlers = new HashSet();
Iterator i$1 = ((Set)e.getValue()).iterator();
while(i$1.hasNext()) {
Method m = (Method)i$1.next();
handlers.add(new EventHandler(listener, m));
}
handlersInMethod.put(e.getKey(), handlers);
}
}
return handlersInMethod;
}
private AnnotatedHandlerFinder() {
}
}
网友评论