Otto是Event Bus 模式的一种实现, 使用它可使事件的发送与处理解耦, 为了坚挺某个事件没必要再去实现相应的接口, 只需简单的加标注、注册就能够实现。java
首先来看两种标注:app
subscribe:this
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Subscribe { }
produce:spa
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Produce { }
第一个方法标注标识一个方法是事件的消费者(事件的监听者), 第二个方法标注标识一个方法可以产生事件对象。.net
对于拥有事件监听方法的对象 以及拥有事件产生方法的对象, 分别有EventHandler 和 EventProducer 对象对其进行包装:
code
EventProducer 的target对象是被包装的对象, 它有一个 具体 @Produce 标注的方法,该方法对象即 method对象
class EventProducer { /** Object sporting the producer method. */ final Object target; /** Producer method. */ private final Method method; /** Object hash code. */ private final int hashCode; /** Should this producer produce events? */ private boolean valid = true; EventProducer(Object target, Method method) { .. this.target = target; this.method = method; method.setAccessible(true); // Compute hash code eagerly since we know it will be used frequently and we cannot estimate the runtime of the // target's hashCode call. final int prime = 31; hashCode = (prime + method.hashCode()) * prime + target.hashCode(); } /** * If invalidated, will subsequently refuse to produce events. * Should be called when the wrapped object is unregistered from the Bus. */ public void invalidate() { valid = false; } /** * Invokes the wrapped producer method. */ public Object produceEvent() throws InvocationTargetException { if (!valid) { throw new IllegalStateException(toString() + " has been invalidated and can no longer produce events."); } try { return method.invoke(target); } catch (IllegalAccessException e) { throw new AssertionError(e); } catch (InvocationTargetException e) { if (e.getCause() instanceof Error) { throw (Error) e.getCause(); } throw e; } } ... }
EventHander:接口
这里的 target 具备一个加了 @Subscribe 标注的 方法, 由method引用事件
class EventHandler { /** Object sporting the handler method. */ private final Object target; /** Handler method. */ private final Method method; /** Object hash code. */ private final int hashCode; /** Should this handler receive events? */ private boolean valid = true; EventHandler(Object target, Method method) { ... this.target = target; this.method = method; method.setAccessible(true); // Compute hash code eagerly since we know it will be used frequently and we cannot estimate the runtime of the // target's hashCode call. final int prime = 31; hashCode = (prime + method.hashCode()) * prime + target.hashCode(); } /** * Invokes the wrapped handler method to handle {@code event}. */ public void handleEvent(Object event) throws InvocationTargetException { if (!valid) { throw new IllegalStateException(toString() + " has been invalidated and can no longer handle events."); } try { method.invoke(target, event); } catch (IllegalAccessException e) { throw new AssertionError(e); } catch (InvocationTargetException e) { if (e.getCause() instanceof Error) { throw (Error) e.getCause(); } throw e; } } ... }