RxJava是一个基于观察者模式的异步开发库,通常我们在项目中结合Retrofit来执行网络请求,如下
HttpRepo.getUnReadMsgInfo(AppSetting.getInstance().getUserPhone())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BaseObserver() {
@Override
public void onNext(UnusedMsgInfo unusedMsgInfo) {
super.onNext(unusedMsgInfo);
getView().showMsgNum(unusedMsgInfo);
}
});
代码中请求未读数量信息,在onNext中显示未读数量,看似没有什么问题,但是当Activity被finish时,Observable未取消订阅,BaseObserver为匿名内部类持有Actitivty引用,导致内存泄漏.
RxLifecycle是一个能够自动绑定生命周期的开源库,解决项目中的订阅关系解除。
首先导入gradle
implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
使Activity继承RxAppCompatActivity,Fragment继承与RxFragment,对于需要自动绑定生命周期的Obsevable有两种绑定方法
HttpRepo.getUnReadMsgInfo(AppSetting.getInstance().getUserPhone())
.observeOn(AndroidSchedulers.mainThread())
.compose(bindUntilEvent(ActivityEvent.Destory))
.subscribe(new BaseObserver() {
@Override
public void onNext(UnusedMsgInfo unusedMsgInfo) {
super.onNext(unusedMsgInfo);
getView().showMsgNum(unusedMsgInfo);
}
});
上述代码表示绑定Activity的Destory,当Activity的onDestory调用时,Observable将解除绑定,fragment则是bindUntilEvent(FragmentEvent.Destory)
库中定义有ActivityEvent和FragmentEvent枚举,枚举了Fragment和Activity的各个生命周期
HttpRepo.getUnReadMsgInfo(AppSetting.getInstance().getUserPhone())
.observeOn(AndroidSchedulers.mainThread())
.compose(bindToLifecycle())
.subscribe(new BaseObserver() {
@Override
public void onNext(UnusedMsgInfo unusedMsgInfo) {
super.onNext(unusedMsgInfo);
getView().showMsgNum(unusedMsgInfo);
}
});
bindToLifecycle是自动绑定当前生命周期,每个周期都有对应的周期解除,
如当前Actiivty为onResume状态,则Observable会在onPause解除
Activity对应关系有如下几种
Fragment对应关系如下:
对应关系可查看RxLifecycleAndroid中的ACTIVITY_LIFECYCLE和FRAGMENT_LIFECYCLE
首先我们看RxAppCompatActivity源码
public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject lifecycleSubject = BehaviorSubject.create();
@Override
@NonNull
@CheckResult
public final Observable lifecycle() {
return lifecycleSubject.hide();
}
@Override
@NonNull
@CheckResult
public final LifecycleTransformer bindUntilEvent(@NonNull ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final LifecycleTransformer bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
@Override
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(ActivityEvent.CREATE);
}
@Override
@CallSuper
protected void onStart() {
super.onStart();
lifecycleSubject.onNext(ActivityEvent.START);
}
@Override
@CallSuper
protected void onResume() {
super.onResume();
lifecycleSubject.onNext(ActivityEvent.RESUME);
}
@Override
@CallSuper
protected void onPause() {
lifecycleSubject.onNext(ActivityEvent.PAUSE);
super.onPause();
}
@Override
@CallSuper
protected void onStop() {
lifecycleSubject.onNext(ActivityEvent.STOP);
super.onStop();
}
@Override
@CallSuper
protected void onDestroy() {
lifecycleSubject.onNext(ActivityEvent.DESTROY);
super.onDestroy();
}
}
代码中创建了一个BehaviorSubject,在每个生命周期函数中向其发射对应周期事件.
绑定方法bindUntilEvent中调用RxLifecycle.bindUntilEvent(lifecycleSubject, event)传入了创建的subject,进入具体方法中,可以看到调用了takeUntilEvent方法
public static LifecycleTransformer bindUntilEvent(@Nonnull final Observable lifecycle,
@Nonnull final R event) {
checkNotNull(lifecycle, "lifecycle == null");
checkNotNull(event, "event == null");
return bind(takeUntilEvent(lifecycle, event));
}
进入到takeUntilEvent方法,方法中对subject使用filter方法过滤Event,即返回的新的observable只接收传入的event。
private static Observable takeUntilEvent(final Observable lifecycle, final R event) {
return lifecycle.filter(new Predicate() {
@Override
public boolean test(R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(event);
}
});
}
再回到bindUnitilEvent中的bind方法,返回一个LifecycleTransformer对象
public static LifecycleTransformer bind(@Nonnull final Observable lifecycle) {
return new LifecycleTransformer<>(lifecycle);
}
查看LifecycleTransfomer类
public final class LifecycleTransformer implements ObservableTransformer,
FlowableTransformer,
SingleTransformer,
MaybeTransformer,
CompletableTransformer
{
final Observable> observable;
LifecycleTransformer(Observable> observable) {
checkNotNull(observable, "observable == null");
this.observable = observable;
}
@Override
public ObservableSource apply(Observable upstream) {
return upstream.takeUntil(observable);
}
@Override
public Publisher apply(Flowable upstream) {
return upstream.takeUntil(observable.toFlowable(BackpressureStrategy.LATEST));
}
@Override
public SingleSource apply(Single upstream) {
return upstream.takeUntil(observable.firstOrError());
}
@Override
public MaybeSource apply(Maybe upstream) {
return upstream.takeUntil(observable.firstElement());
}
@Override
public CompletableSource apply(Completable upstream) {
return Completable.ambArray(upstream, observable.flatMapCompletable(Functions.CANCEL_COMPLETABLE));
}
@Override
public boolean equals(Object o) {
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
LifecycleTransformer> that = (LifecycleTransformer>) o;
return observable.equals(that.observable);
}
@Override
public int hashCode() {
return observable.hashCode();
}
@Override
public String toString() {
return "LifecycleTransformer{" +
"observable=" + observable +
'}';
}
}
LifecycleTransformer类实现了各种rxjava中的变换接口,我们看其中一个ObservableTransform的实现
public ObservableSource apply(Observable upstream) {
return upstream.takeUntil(observable);
}
upstream即为上游的Observable,对上游Observable执行takeUnit操作,传入的observable为takeUntilEvent方法返回的Observable。
takeUntil操作符监视传入的observable,当传入的observable发射事件时,会停止上游observable的事件发送。
将代码结合后,可得最终代码为
upstream.takeUntil(lifecycleSubject.filter(new Predicate() {
@Override
public boolean test(R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(event);
}
});
so,以bindUntilEvent(ActivityEvent.DESTORY)为例,当Activity执行到onDestory时,lifecycleSubject发射ActivityEvent.DESTORY事件,此时upstream即取消了订阅,实现了生命周期的绑定
再看bindToLifecycle方法是如何做到自动绑定当前生命周期,进入方法,看到调用的是RxLifecycleAndroid.bindActivity方法
public final LifecycleTransformer bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
进入bindActivity方法,调用了bind方法,传入ACTIVITY_LIFECYCLE对象
public static LifecycleTransformer bindActivity(@NonNull final Observable lifecycle) {
return bind(lifecycle, ACTIVITY_LIFECYCLE);
}
进入bind方法
public static LifecycleTransformer bind(@Nonnull Observable lifecycle,
@Nonnull final Function correspondingEvents) {
checkNotNull(lifecycle, "lifecycle == null");
checkNotNull(correspondingEvents, "correspondingEvents == null");
return bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents));
}
再进入takeUntilCorrespondingEvent方法
private static Observable takeUntilCorrespondingEvent(final Observable lifecycle,
final Function correspondingEvents) {
return Observable.combineLatest(
lifecycle.take(1).map(correspondingEvents),
lifecycle.skip(1),
new BiFunction() {
@Override
public Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(bindUntilEvent);
}
})
.onErrorReturn(Functions.RESUME_FUNCTION)
.filter(Functions.SHOULD_COMPLETE);
}
使用combineLatest操作符结合两个observable
先看lifecycle.take(1).map(correspondingEvent)
take(1)表示取第一个元素,再进行map操作,此处传入的是ACTIVITY_LIFECYCLE,看看ACTIVITY_LIFECYCLE
private static final Function ACTIVITY_LIFECYCLE =
new Function() {
@Override
public ActivityEvent apply(ActivityEvent lastEvent) throws Exception {
switch (lastEvent) {
case CREATE:
return ActivityEvent.DESTROY;
case START:
return ActivityEvent.STOP;
case RESUME:
return ActivityEvent.PAUSE;
case PAUSE:
return ActivityEvent.STOP;
case STOP:
return ActivityEvent.DESTROY;
case DESTROY:
throw new OutsideLifecycleException("Cannot bind to Activity lifecycle when outside of it.");
default:
throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");
}
}
};
这里就是对每个Event进行了转换,CREATE对应DESTORY等等等。。。
所以observable.take(1).map方法发射元素是当前Activity周期所对应的解除周期。
再看observable.skip(1)即跳过1个元素,即跳过当前最后一次的周期
然后用combineLaster结合两个obserable,这里对Event进行equal操作,返回boolean值
combineLatest是RxJava本身提供的一个常用的操作符,它接受两个或以上的Observable和一个FuncX闭包。当传入的Observable中任意的一个发射数据时,combineLatest将每个Observable的最近值(Lastest)联合起来(combine)传给FuncX闭包进行处理
so,再结合实际说明,当upstream在onCreate后订阅,observable.take(1).map发射元素为ActivityEvent.DESTORY,之后Activity执行到onPause,事件为ActivityEvent.PAUSE,执行合并操作,ActivityEvent.DESTORY.equal(ActiivtyEvent.PAUSE)返回false,后面还有filter操作,过滤掉了false,所以不会接触绑定,当Activity到onDestory时,发射ActivityEvent.DESTORY,这时候upstream即会解除订阅,实现生命周期自动绑定.