但是RxJava可能会存在内存泄漏的情况,需要手动取消订阅关系。(使用RxJava发布一个订阅后,当Activity被finish,此时订阅逻辑还未完成,如果没有及时取消订阅,RxJava仍然持有Activity的引用,会导致Activity无法被回收,从而引发内存泄漏。)
RxLifecycle 通过和Activity/ fragment绑定并监听其生命周期,动态的实现subscription的解绑
依赖引入
// RxLifecycle基础库
implementation 'com.trello.rxlifecycle2:rxlifecycle:2.1.0'
// Android使用的库,里面定义了Android的生命周期方法
// 内部引用了基础库,如果使用此库则无需再引用基础库
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.1.0'
// Android组件库,里面定义了例如RxAppCompatActivity、RxActivity、RxFragment之类的Android组件
// 内部引用了基础库和Android库,如果使用此库则无需再重复引用
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
简单使用:
1、引入依赖(会自动引入rxlifecycle / rxlifecycle-android)
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
2、当前Activity继承自RxAppCompatActivity 或 RxFragmentActivity 或 RxActivity
3、通过compose与当前Activity的生命周期进行绑定,即可动态取消订阅
val retrofit = Retrofit.Builder()
.baseUrl("https://xxx.xx/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync())
.client(OkHttpClient())
.build()
val netService = retrofit.create(AccessApi::class.java)
netService.updateUser(1, "zhen")
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.compose(this.bindToLifecycle()) //方式1
.compose(this.bindUntilEvent(ActivityEvent.DESTROY)) //方式2
.subscribe({t: UserBean ->
TODO("not implemented")
}, {e: Throwable ->
})
使用很简单,怎么实现的呢?进入源码分析
主要有几个问题需要处理:
我们的Activity/Fragment需要继承自RxLifecycle提供的Activity/Fragment
在RxActivity的生命周期回调函数里,分别会通过lifecycleSubject发送一个对应的ActivityEvent事件。
如在onCreate()中会发送ActivityEvent.CREATE。
同理,在RxFragment的生命周期函数里,会发送对应的FragmentEvent事件
lifecycleSubject是一个BehaviorSubject对象
这样,继承自RxLifecycle提供的Activity/Fragment,就可以监听它们的生命周期,并发出指定的事件。
public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
public final Observable<ActivityEvent> lifecycle() {
return lifecycleSubject.hide();
}
public final <T> LifecycleTransformer<T> bindUntilEvent(ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(ActivityEvent.CREATE);
}
protected void onStart() {
super.onStart();
lifecycleSubject.onNext(ActivityEvent.START);
}
protected void onResume() {
super.onResume();
lifecycleSubject.onNext(ActivityEvent.RESUME);
}
protected void onPause() {
lifecycleSubject.onNext(ActivityEvent.PAUSE);
super.onPause();
}
protected void onStop() {
lifecycleSubject.onNext(ActivityEvent.STOP);
super.onStop();
}
protected void onDestroy() {
lifecycleSubject.onNext(ActivityEvent.DESTROY);
super.onDestroy();
}
}
前面已经可以监听Activity/Fragment的生命周期,并会在相应生命周期回调时,发出一个event。
那在接收到这个指定的event时,需要进行截断。
RxJava中的takeUntil方法解析:
当第二个observable发送了一条数据或者终止时,终止原observable发送的所有数据。
(如图所示,observable2发送了红色八边形,observable1 之后的蓝色球和紫色球不再发送)
红色八边形就是发出的event事件。(ActivityEvent/FragmentEvent)
圆球就是所有的网络请求Observable< Object>
Observable以流的方式进行传输,netService.updateUser(1, “zhen”),就是一个upStream(上流)
upstream.compose(composer) // upstream应用一个composer对象,进行apply适配处理
composer.apply(upstream) //
upstream.takeUntil(observable) //upstream一直正常发送处理,直到接收到observable,就断开流
public final <R> Observable<R> compose(ObservableTransformer<? super T, ? extends R> composer) {
return composer.apply(this);
}
那示例中的composer就是this.bindToLifecycle()、this.bindUntilEvent(ActivityEvent.DESTROY)。
也就是个LifecycleTransformer< T>对象。
LifecycleTransformer< T>实现了ObservableTransformer< T, T>接口,也实现了它的apply方法。
public interface ObservableTransformer<Upstream, Downstream> {
ObservableSource<Downstream> apply(Observable<Upstream> upstream);
}
//LifecycleTransformer< T>实现了ObservableTransformer< T, T>接口,也实现了它的apply方法
public final class LifecycleTransformer<T> implements ObservableTransformer<T, T>,
FlowableTransformer<T, T>,
SingleTransformer<T, T>,
MaybeTransformer<T, T>,
CompletableTransformer {
final Observable<?> observable;
LifecycleTransformer(Observable<?> observable) {
this.observable = observable;
}
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
return upstream.takeUntil(observable);
}
}
和Activity/Fragment进行生命周期绑定,this必须要实现LifecycleProvider
public interface LifecycleProvider<E> {
Observable<E> lifecycle();
<T> LifecycleTransformer<T> bindUntilEvent(@Nonnull E event);
<T> LifecycleTransformer<T> bindToLifecycle();
}
RxLifecycle里提供的Activity / Fragment 实现了LifecycleProvider< ActivityEvent>或者< FragmentEvent>
//RxActivity.java
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
ACTIVITY_LIFECYCLE :对应下面的map操作, 根据发布订阅的生命周期,得到应该取消订阅的生命周期。bindUntilEvent(event) 即手动设置自己想要取消订阅的时间。
RxJava的combineLatest方法解析
lifecycle.take(1).map(correspondingEvents),
只取lifecycleSubject发送的一个事件,且经过correspondingEvents映射,
也就是CREATE映射为DESTROY
lifecycle.skip(1),
跳过接收lifecycleSubject的第一个事件CREATE,
接收其余所有事件START/RESUME/PAUSE/STOP/DESTROY
function:只有当source1的activityEvent等于source2的activityEvent时,返回true
在指定的生命周期时候就会发送true,其余时候发送false
最后配合filter操作符,只有在true的时候才能发送
//RxLifecycleAndroid.java
//这里lifecycle是上文的lifecycleSubject对象
//对应各个生命周期,发出各个ActivityEvent
public static <T> LifecycleTransformer<T> bindActivity(final Observable<ActivityEvent> lifecycle) {
return bind(lifecycle, ACTIVITY_LIFECYCLE);
}
public static <T, R> LifecycleTransformer<T> bind(Observable<R> lifecycle,
final Function<R, R> correspondingEvents) {
return bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents));
}
//这里的lifecycle就是上面的observale
//也就是只要接收到这个lifecycle事件,upSteam就会进行截断
public static <T, R> LifecycleTransformer<T> bind(final Observable<R> lifecycle) {
return new LifecycleTransformer<>(lifecycle);
}
private static <R> Observable<Boolean> takeUntilCorrespondingEvent(final Observable<R> lifecycle,
final Function<R, R> correspondingEvents) {
return Observable.combineLatest( //对observable1和observable2,应用function
//只取lifecycleSubject发送的一个事件,且经过correspondingEvents映射,也就是CREATE映射为DESTROY
lifecycle.take(1).map(correspondingEvents),
//跳过接收lifecycleSubject的第一个事件CREATE,接收其余所有事件START/RESUME/PAUSE/STOP/DESTROY
lifecycle.skip(1),
new BiFunction<R, R, Boolean>() {
@Override
public Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(bindUntilEvent);
}
})
.onErrorReturn(Functions.RESUME_FUNCTION)
.filter(Functions.SHOULD_COMPLETE);
}
// Figures out which corresponding next lifecycle event in which to unsubscribe, for Activities
//针对Activity,形成一个映射关系
private static final Function<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE =
new Function<ActivityEvent, ActivityEvent>() {
@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");
}
}
};
lifecycleSubject 在Activity的各个生命周期中发出的event和指定的event比较,相同则发送事件
即通过bindUntilEvent(event) 手动决定在哪个生命周期里,对网络请求进行取消订阅
//RxActivity.java
public final <T> LifecycleTransformer<T> bindUntilEvent(ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
//RxLifecycle.java
public static <T, R> LifecycleTransformer<T> bindUntilEvent(final Observable<R> lifecycle,
final R event) {
return bind(takeUntilEvent(lifecycle, event));
}
//event指定取消订阅的时机
//lifecycleEvent,lifecycle发送的事件
//lifecycle就是上面的lifecycleSubject,发送create/start/resume/pause/stop/destroy
private static <R> Observable<R> takeUntilEvent(final Observable<R> lifecycle, final R event) {
return lifecycle.filter(new Predicate<R>() {
@Override
public boolean test(R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(event);
}
});
}
//这里的lifecycle是takeUntilEvent返回的,只有当lifecycleEvent.equals(event)时,才发送事件
public static <T, R> LifecycleTransformer<T> bind(final Observable<R> lifecycle) {
return new LifecycleTransformer<>(lifecycle);
}
总结:
1、upstream.compose(composer) -> upstream.takeUntil(observer),收到observer,则取消订阅关系
2、创建subjectBehavior, Activity/Fragment不同生命周期内会发出不同的Event事件
3、在指定生命周期或者对应生命周期会解除upstream的订阅关系。
指定取消订阅的event,会取出不同生命周期里发出的event事件和这个指定的event进行比较;
4、如果匹配成功, 会发送一个observable对象,upstream受到observable的作用,从而取消订阅关系。