RxJava教程之生命周期管理

上篇

  Rx主要的亮点是:它并不知道一系列事件什么时候发送或中断时,但是你能控制你什么时候开始接受这一系列事件或什么时候停止接受,这样,订阅者不再和原始事件系列发生源耦合,Rx能提给供你有关事件的各种订阅方式。你可以任意地订阅,也可以取消订阅,这种订阅到取消订阅之间的周期我们可以称为订阅的生命周期,RxJava提供各种灵活强大的订阅生命周期管理。

订阅

  我们看看Observable.subscribe几个重要方法参数:

Subscription    subscribe()
Subscription    subscribe(Action1<? super  T> onNext)
Subscription    subscribe(Action1<? super  T> onNext, Action1< java.lang .Throwable> onError)
Subscription    subscribe(Action1<? super  T> onNext, Action1< java.lang .Throwable> onError, Action0 onComplete)
Subscription    subscribe(Observer<? super  T> observer)
Subscription    subscribe(Subscriber<? super  T> subscriber)

上述各种subscribe()接口是消费使用各种推送的事件,但是不会执行任何动作action,具体真正action动作会作为参数提供给接口方法,如果你不提供任何action,事件实际上会被忽视,也就是不做任何处理。

Subject< Integer,  Integer> s = ReplaySubject.create();
s.subscribe(
    v -> System.out.println(v),
    e -> System.err.println(e));
s.onNext(0);
s.onError(new Exception("Oops "));

输出:

0
java.lang.Exception: Oops 

如果我们不提供错误处理的函数,那么在onError被调用时,OnErrorNotImplementedException 会被抛出。

 

取消订阅

  你也可以在一个系列事件中断前停止接受事件值,前面每个subscribe 方法返回都是一个Subscription实例,这是一个有两个方法的接口:

boolean isUnsubscribed()
void unsubscribe()

调用unsubscribe将会停止接受观察者向你发送的事件。

Subject< Integer,  Integer>  values = ReplaySubject.create();
Subscription subscription = values.subscribe(
    v -> System.out.println(v),
    e -> System.err.println(e),
    () -> System.out.println("Done ")
);
values.onNext(0);
values.onNext(1);
subscription.unsubscribe();
values.onNext(2);
输出结果是两个数值:0和1

没有输出2数值,因为我们已经在发送数值2之前取消了订阅,一个观察者取消订阅并不影响对同一个被观察者的其他观察者的订阅接受情况。

 

onError 和 onCompleted

  这两个方法意味着中断一个事件系列,可观察者(被观察者)一旦在这两个方法以后就不再发射任何事件,尽管你的代码可能还会有发送事件:

Subject< Integer,  Integer>  values = ReplaySubject.create();
Subscription subscription1 = values.subscribe(
    v -> System.out.println("First:  " + v),
    e -> System.out.println("First:  " + e),
    () -> System.out.println("Completed ")
);
values.onNext(0);
values.onNext(1);
values.onCompleted();
values.onNext(2);

输出:

First: 0
First: 1
Completed 

上述代码尽管可观察者还在onCompleted以后发送事件数值2,但是运行时观察者并没有接受到。

 

释放资源

  一个Subscription 将会和其使用的资源绑定,因此,你必须记得处理订阅的善后工作,,使用Subscriptions 这个静态工厂创建一个Subscription,可将Subscription与一个必需的资源绑定:

Subscription s = Subscriptions.create(() -> System.out.println("Clean "));
s.unsubscribe();

输出结果: Clean

Subscriptions.create创建的订阅Subscription需要有一个取消订阅的动作,以便释放资源,这些方式有如下几种:

  • Subscriptions.empty()返回的一个订阅Subscription是不需要做善后工作的,当你需要一个订阅Subscription并不需要释放任何资源是有效。
  • Subscriptions.from(Subscription... subscriptions) 返回的订阅Subscription是当其结束时需要处理多个其他订阅的善后工作。
  • Subscriptions.unsubscribed() 返回一个已经取消订阅做好善后工作的订阅Subscription

订阅Subscription有如下几种实现子类:

  • BooleanSubscription
  • CompositeSubscription
  • MultipleAssignmentSubscription
  • RefCountSubscription
  • SafeSubscriber
  • Scheduler.Worker
  • SerializedSubscriber
  • SerialSubscription
  • Subscriber
  • TestSubscriber

It is interesting to note that Subscriber also implements Subscription. This means that we can also use a reference to a Subscriber to terminate a subscription.

请注意Subscriber也会实现接口Subscription,这意味着我们能使用一个指向Subscriber的引用来中断一个订阅。

下一篇事件系列

更多RxJava专题