RxLifeCycle
2020-03-28 本文已影响0人
ivotai
介绍
在 内存泄漏 中介绍了使用 Disposable 来避免内存泄漏。
但这个简单的方法需要重载 onDestory 方法,有侵入性,不遭人待见。
更多的人选择用 RxLifeCycle 库来处理内存泄漏的问题。
RxLifeCycle 的库有很多,本篇使用 https://github.com/florent37/RxLifecycle
使用
因为这个库没有更新到 RxJava3 ,所以只能降低 RxJava 的版本。
implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'com.github.florent37:rxlifecycle:2.0.5'
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
fetchData()
}
private fun fetchData() {
Observable.interval(1, TimeUnit.SECONDS)
.compose(disposeOnDestroy(lifecycle))
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
textView.text = it.toString()
}
}
}
实测表明,一行代码解决了内存泄漏。
分析
首先,明确要做的是什么?
在 Activity 进入 onDestroy 状态时, dispose 这个 Disposable。
第一步。
得益于 LifeCycle,写一个简单的 LifecycleObserver 就能监控 onDestroy 的发生。
class TestObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
Logger.d("onDestroy")
}
}
第二步。
然后修改代码,使用 Subject
class TestObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
subject.onNext(any) // 随便是什么类型
}
}
subject 的 onNext 是群体发射,通知被订阅的 Observer 响应。
第三步。
private val subject = PublishSubject.create<Any>()
private fun fetchData() {
Observable.interval(1, TimeUnit.SECONDS)
.doOnSubscribe { disposable ->
subject.subscribe { disposable.dispose() }
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
textView.text = it.toString()
}
}
subject 早早订阅了 Observer,但只有当 onDestory 时才会通知 Observer 响应,而响应的结果就是 dispose。
后话
早期的 RxLifeCycle 库,因为那时还没有 LifeCycle 这个东西。他们通过给 Activity 或者 Fragment 添加不可见的子 Fragment ,重载子 Fragment 的生命周期函数来... 反正很麻烦。
而即使有了 LifeCycle ,类库的实现者为了面面俱到(ObservableTransformer的变种有5种,生命周期的 event 又有很多种),为了使用者绝对的方便(一行代码搞定)也会把类库写的很繁杂。