Otto的使用和源码分析

Otto是Square为Android设计的一款轻量级事件总线,用于替代Intent、Handler和Broadcast。本文介绍了如何下载、使用Otto,以及详细解析了Otto的源码,包括@Produce和@Subscribe注解、ThreadEnforcer和HandlerFinder接口,以及Bus类的工作原理。
摘要由CSDN通过智能技术生成

Otto

Otto是square的一个event bus实现。

Event bus是一款针对Android优化的发布/订阅事件总线,主要功能是替代Intent、Handler、BroadCast
在Activity、Fragment、Service、Thread之间传递消息。其优点是开销小,代码更优雅,以及
将发送者和接收者解耦。

下载

在Android studio的module级别的build.gradle中dependencies下加入

compile 'com.squareup:otto:1.3.8'

使用

1.新建一个Bus实例,建议使用单例。

java
Bus bus = new Bus();

2.事件发布是非常重要的,因为它可以通知相应事件的订阅者某个动作已经发生。任何的类实例都可以
通过Bus发布事件,并且只有订阅了该事件的订阅者才会收到相应通知。

通过post方法发布一个新的事件

java
bus.post(new AnswerAvailableEvent(42));

除此之外,还有另外一种方法可以发布事件,这种形式会在Bus调用register方法时立即发布事件。
java
@Produce
public AnswerAvailableEvent produceAnswer() {
// Assuming 'lastAnswer' exists.
return new AnswerAvailableEvent(this.lastAnswer);
}

在方法级别上添加@Produce注解,方法的访问权限一定得是public的,并且其返回值类型是所发布
的事件类型。

这种事件发布形式还必需得在类实例中注册Bus实例
java
bus.register(this);

否则这个事件是无法让其订阅者接收到事件通知的。

3.订阅一个事件,你需要在方法级别上添加一个@Subscribe的注解。这个方法只能带有一个参数,
并且类型是你需要的订阅事件类型。

订阅一个事件,需要这样做

java
@Subscribe
public void answerAvailable(AnswerAvailableEvent event) {
// TODO: React to the event somehow!
}

需要注意的是,上面的方法其访问权限一定得是public的,其他无限制。

为了能够接收到事件,类实例需要注册Bus。通过下面方式注册
java
bus.register(this);

我们可以在适当的时候调用unregister方法取消Bus的注册
java
bus.unregister(this);

我们可以在Activity和Fragment的OnResume方法中注册Bus,然后在OnPause方法中取消注册。

4.默认的,新建的Bus是在主线程上活动的。
java
Bus bus1 = new Bus();
Bus bus2 = new Bus(ThreadEnforcer.MAIN);

上面两句代码是等价的。

你还可以实例化一个在任何线程都可以活动的Bus,
java
Bus bus3 = new Bus(ThreadEnforcer.ANY);

5.对于上面的使用方法,我是参照官方文档做一个大概的说明。大家可以使用git clone下官方提供
的sample研究具体的使用方法。

链接: https://github.com/square/otto

源码分析

Otto的源码只有九个类,阅读起来还是很容易理解的。

先看@Produce、@Subscribe这两个注解的定义。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Produce {
   

}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Subscribe {
   

}

可以看出这两个注解都是在jvm运行时可获得的,并且都是作用在方法级别上。

再来看ThreadEnforcer、HandlerFinder两个接口。

public interface ThreadEnforcer {
   

  /**
   * 强制bus在某个确定的线程
   */
  void enforce(Bus bus);

  /** A {@link ThreadEnforcer} that does no verification. */
  ThreadEnforcer ANY = new ThreadEnforcer() {
    @Override public void enforce(Bus bus) {
      // Allow any thread.
    }
  };

  /** A {@link ThreadEnforcer} that confines {@link Bus} methods to the main thread. */
  ThreadEnforcer MAIN = new ThreadEnforcer() {
    @Override public void enforce(Bus bus) {
      if (Looper.myLooper() != Looper.getMainLooper()) {
        throw new IllegalStateException("Event bus " + bus +
        " accessed from non-main thread " + Looper.myLooper());
      }
    }
  };

}

ThreadEnforcer里面提供了两个默认的实现,其中我们新创建的Bus实例是默认使用Android的主线程的。

/** Finds producer and subscriber methods. */
interface HandlerFinder {

  Map<Class<?>, EventProducer> findAllProducers(Object listener);

  Map<Class<?>, Set<EventHandler>> findAllSubscribers(Object listener);


  HandlerFinder ANNOTATED = new HandlerFinder() {
    @Override
    public Map<Class<?>, EventProducer> findAllProducers(Object listener) {
      return AnnotatedHandlerFinder.findAllProducers(listener);
    }

    @Override
    public Map<Class<?>, Set<EventHandler>> findAllSubscribers
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值