Rxlifecycle 2.1.0原理分析

文章目录

      • 简单使用
      • 源码分析
        • 如何监听activity/fragment的生命周期
        • 请求如何进行截断
        • Observable#compose(composer)方法解析
        • composer是LifecycleTransformer对象
        • LifecycleTransformer是如何构建出来的
          • bindToLifecycle分析
          • bindUntilEvent()分析

我们通常采用Retrofit + RxJava + Gson 进行网络请求通讯

但是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 ->
        })

源码分析

使用很简单,怎么实现的呢?进入源码分析
​​Rxlifecycle 2.1.0原理分析_第1张图片
主要有几个问题需要处理:

  1. 需要监听activity/fragment的生命周期
  2. 在特定的生命周期时,需要截断这个网络请求(耗时异步操作)

如何监听activity/fragment的生命周期

  • 我们的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();
    }
}

请求如何进行截断

  • bindToLifecycle:activity onDestroy时,就会断开流,取消网络请求的订阅
  • bindUntilEvent:直到收到相应的event事件,就会断开流,取消网络请求的订阅

前面已经可以监听Activity/Fragment的生命周期,并会在相应生命周期回调时,发出一个event。
那在接收到这个指定的event时,需要进行截断。

RxJava中的takeUntil方法解析:

当第二个observable发送了一条数据或者终止时,终止原observable发送的所有数据。
(如图所示,observable2发送了红色八边形,observable1 之后的蓝色球和紫色球不再发送)
红色八边形就是发出的event事件。(ActivityEvent/FragmentEvent)
圆球就是所有的网络请求Observable< Object>
​​Rxlifecycle 2.1.0原理分析_第2张图片

Observable#compose(composer)方法解析

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是LifecycleTransformer对象

那示例中的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);
    }
}

LifecycleTransformer是如何构建出来的

和Activity/Fragment进行生命周期绑定,this必须要实现LifecycleProvider

  • this.bindToLifecycle()//方式1
  • this.bindUntilEvent(ActivityEvent.DESTROY) //方式2
public interface LifecycleProvider<E> {
    Observable<E> lifecycle();
    <T> LifecycleTransformer<T> bindUntilEvent(@Nonnull E event);
    <T> LifecycleTransformer<T> bindToLifecycle();
}

RxLifecycle里提供的Activity / Fragment 实现了LifecycleProvider< ActivityEvent>或者< FragmentEvent>

bindToLifecycle分析
//RxActivity.java
 public final <T> LifecycleTransformer<T> bindToLifecycle() {
        return RxLifecycleAndroid.bindActivity(lifecycleSubject);
    }

ACTIVITY_LIFECYCLE :对应下面的map操作, 根据发布订阅的生命周期,得到应该取消订阅的生命周期。bindUntilEvent(event) 即手动设置自己想要取消订阅的时间。

RxJava的combineLatest方法解析

Rxlifecycle 2.1.0原理分析_第3张图片

  • source1:BehaviorSubject< ActivityEvent>
lifecycle.take(1).map(correspondingEvents),
只取lifecycleSubject发送的一个事件,且经过correspondingEvents映射,
也就是CREATE映射为DESTROY
  • source2:BehaviorSubject< ActivityEvent>
 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");
            }
        }
    };
bindUntilEvent()分析

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的作用,从而取消订阅关系。

你可能感兴趣的:(三方开源库)