前言
在新项目中尝试使用Retrofit和RxJava,不可避免遇到了页面关闭取消网络请求的需求,原先OkHttp支持请求携带target来取消请求。在使用Observable使用相关操作符带来大幅度便利的同时也出现了难以回收的问题。
解决方案1:在BaseActivity中记录一个List<Subscription>
,每次调用网络请求add进队列。在页面onDestory统一unsubscribe。后来发现这个方法也太搓了⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄
解决方案2:后来发现一个类CompositeSubscription,相当于统一管理Subscription的类。恩,那就用这个来代替List,啊呸。这不是换汤不换药吗,遂放弃
解决方案3:在万能的GitHub发现了RxLifecycle,专门解决RxJava在Android上的内存泄露问题,在下载发现使用Demo确实能够解决问题,那么它是基于什么原理呢?
提前剧透:
RxLifecycle的原理是不是基于自动调用unsubscribe的。
RxLifecycle的原理是不是基于自动调用unsubscribe的。
RxLifecycle的原理是不是基于自动调用unsubscribe的。
初窥门径
大致瞄了下,基于RxJava所推荐的的链式结构,在Compose
操作符对其进行生命周期的绑定,对操作符还不甚了解的小伙伴点这里。
需要绑定生命周期的Activity需继承RxAppCompatActivity,在RxAppCompatActivity下有个比较陌生的东西,BehaviorSubject
网上对此的描述:当Observer订阅了一个BehaviorSubject,它一开始就会释放Observable最近释放的一个数据对象,当还没有任何数据释放时,它则是一个默认值。接下来就会释放Observable释放的所有数据。如果Observable因异常终止,BehaviorSubject将不会向后续的Observer释放数据,但是会向Observer传递一个异常通知。
配合源码使用效果更佳⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄,接下来我们继续看demo中调用的bindUntilEvent
的实际上调用了RxLifecycle的bindUntilEvent(lifecycleSubject, event)
传递进了BehaviorSubject
观察者对象和需要的解绑的生命周期枚举。在继续点进去后发现除去非空判断后返回了一个本质是Observable.Transformer
的实现类
这里我们着重看call
方法因为我们在调用Compose
时传入的Transformer
必须要重写call
方法,这里发现了一些新的操作符TakeUntil
TakeFirst
,网上的资料解释如下:
TakeUntil:和SkipUtil恰好相反,只获取takeUntil里的Observable之前的数据
SkipUnitl: 是根据一个标志Observable来判断的,当这个标志Observable没有发射数据的时候,所有源Observable发射的数据都会被跳过;当标志Observable发射了一个数据,则开始正常地发射数据。
一直等到skipUntil发射了数据才能发射源Observable的数据,并忽略了此段时间内的数据TakeFirst:有null数据时会抛空指针异常,要判空处理
和first一样,但在所有数据不满足条件时不会抛出异常,仅仅调用onComplete.
总结来说就是takeUntilEvent
方法会返回一个Observable
对象。在takeUntilEvent
里面对lifecycle进行了TakeFirst
处理,当TakeFirst
操作call
返回true时,TakeUntil
返回的Observable
会停止反射原始Observable
并终止,源码使用这个操作判断是否执行发射原始的Observable
牛刀小试
测试场景:当我们在onCreate中执行一个绑定onDestory要停止的耗时操作。在Compose
绑定后,开启页面后立马将其关闭。此时RxAppCompatActivity 中会依次执行onPause,onStop,onDestory方法将执行onNext(ActivityEvent.***)
,然后方法将会跳入TakeFirst
的判断,如果传入的枚举与绑定的生命周期equals==true,那么就告诉TakeUntil
了这个事件流需要终止。TakeUntil
笔者顾名思义理解为就是需要事件流直到某种情况触发。此时将回调onComplete
,不会回调onNext
,在使用Retrofit由于一般都进行了一重数据类型的封装,onSuccess,onFailure,onFinish。这里的调整就抛给大家了O(∩_∩)O哈哈~
PS
这里对2016.11.02的RxLifecycle版本进行分析,RxLifecycle目录下还有很多未对其分析,请听下回分解。
笔者第一次对RxJava进行分析,如有错误,敬请指正!另外谢谢一路上大大无私分享的好文!
Android RxJava操作符一览
RxJava操作符学习笔记
给 Android 开发者的 RxJava 详解
求你指教我们怎样数算自己的日子,好叫我们得着智慧的心。 (诗篇 90:12 和合本)