利用 Jetpack 下的 Lifecycle 获取 Activity/Fragment 的生命周期变化,通过 BehaviorSubject 转化成 Observable,从而通过 Observable.takeUnit(otherObserable) 方法自动完成 Observable 与界面命周期绑定,在日常开发过程中,在该库的管控下,RxJava 相关导致的内存泄漏率为 0%(LeakCanary 检测),强烈推荐使用。
使用 RxJava 的开发者,一定知道 trello/RxLifecycle 项目,本项目 LifecycleTransformer 也是参考了 trello/RxLifecycle,但是个人认为 trello/RxLifecycle 不够简洁,需要继承等等,所以在去年本人就开发了 dhhAndroid/RxLifecycle,更加简洁地管理 RxJava 的生命周期;随着 Google 推出 Jetpack,我发现在 dhhAndroid/RxLifecycle 库中获取界面生命周期的方式 (通过在界面中注入空 Fragment),在 JetPack 中的 Lifecycle 模块中已经实现,所以使用 Kotlin 结合 Jetpack 开发出了本项目。
//support
implementation 'com.android.support:appcompat-v7:28.0.0' //27.0.0 等
//RxJava1
implementation 'io.reactivex:rxjava:1.3.8'
//Rxlife1
implementation 'com.dhh:rxLife1:version'
//support
implementation 'com.android.support:appcompat-v7:28.0.0' //27.0.0 等
//RxJava2
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
//Rxlife2
implementation 'com.dhh:rxLife2:version'
使用(查看 demo)
前置条件:因 support 包中的 AppCompatActivity 和 android.support.v4.app.Fragment 均已实现 LifecycleOwner,所以确保你的项目 BaseActivity 继承于 AppCompatActivity,BaseFragment 继承于 android.support.v4.app.Fragment。
Observable.timer(10, TimeUnit.SECONDS)
// 标准使用模式 , 自动在 [Lifecycle.Event.ON_DESTROY] 注销
.compose(RxLife.with(lifecycleOwner).bindToLifecycle())
// 指定在 [Lifecycle.Event.ON_DESTROY] 注销
.compose(RxLife.with(lifecycleOwner).bindOnDestroy())
// 指定在某一生命周期注销,不常用
.compose(RxLife.with(lifecycleOwner).bindUntilEvent(Lifecycle.Event.ON_DESTROY))
.subscribe { Log.d("RxLife2-onCreate", it.toString()) }
项目中提供了两个注销作用域接口 LifecycleOwnerScope、DisposeScope,其中 LifecycleOwnerScope 的用法是在任意类中比如 Activity、Fragment中如果能获取到 LifecycleOwner 就可以直接让类实现这个接口即可,即可使使用Kotlin的扩展方法进行绑定,用例如下:
class RxLife2Activity : AppCompatActivity(), LifecycleOwnerScope {
override fun getLifecycleOwner(): LifecycleOwner {
if (this is LifecycleOwner) return this
return super.getLifecycleOwner()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_rxlife2)
Observable.timer(1, TimeUnit.SECONDS)
//直接绑定到 Activity 的 onDestroy
.bindOnDestroy()
.subscribe {
}
}
}
DisposeScope(这是RxJava2,RxJava1对应的是 SubscriptionScope)的使用更加广泛,它不依托 LifecycleOwner,对support包版本无要求,只需要在需要使用的类实现此接口,然后在类销毁的时候,调用一下 dispose() 方法即可:
class ViewModelTest : ViewModel(), DisposeScope {
val userName = MutableLiveData<String>()
init {
loadData()
}
fun loadData() {
Observable.timer(5, TimeUnit.SECONDS)
.map { "dhh" }
.doOnSubscribe { Log.d("VVV", "doOnSubscribe") }
.doOnDispose { Log.d("VVV", "doOnDispose") }
.bindOnDestroy()
.subscribe { userName.value = it }
}
override fun onCleared() {
super.onCleared()
dispose()
}
}
interface CustomDisposeScope : DisposeScope {
// add custom extension methods
fun <T> Observable<T>.commit(onNext: (T) -> Unit): Disposable {
return bindOnDestroy().observeOn(AndroidSchedulers.mainThread()).subscribe(onNext, {})
}
}
open class BaseViewModel : ViewModel(), CustomDisposeScope {
override fun onCleared() {
dispose()
}
}
class ViewModelTest : BaseViewModel() {
val userName = MutableLiveData<String>()
init {
loadData()
}
fun loadData() {
Observable.timer(5, TimeUnit.SECONDS)
.map { "dhh" }
.doOnSubscribe { Log.d("VVV", "doOnSubscribe") }
.doOnDispose { Log.d("VVV", "doOnDispose") }
.commit { userName.value = it }
}
}
Copyright 2019 dhhAndroid
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.