公司项目中的网络请求是用Retrofit
+ RxJava2
+ RxLifeCycle
来封装的,由于以前项目中MVP架构与MVVM
架构都有使用,项目结构显得很乱,如今就要求统一使用MVVM
架构,而后就带来了一些问题。以前在ViewModel
中作网络请求时,会将Activity传入到网络请求方法中,用RxLifeCycle
来作网络请求与生命周期的绑定,在Activity
或者Fragment
destroy时取消网络请求,好比:网络
class ExampleViewModel : ViewModel() {
fun download(activity: RxAppCompatActivity, url: String) {
ExampleApi.getNetService()
.download(url)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(activity.bindUtilEvent(ActivityEvent.Destroy))
.subscribe(object: Observer<ResponseBody> {
override fun onNext(responseBody: ResponseBody) {
//doSomething
}
override fun onSubscribe(d: Disposable) {
}
override fun onComplete() {
}
override fun onError(e: Throwable) {
}
})
}
}
复制代码
固然上面那段代码能够经过Kotlin
的扩展方法,变得简练些。通过讨论,决定再也不像ViewModel
中的方法传入Activity
或Fragment
实例,而后又须要某些网络请求在Activity
或Fragment
销毁时取消请求来释放资源。看了ViewModel
与RxLifeCycle
源码以后,发现Activity
或者Fragment
会在destroy时调用VIewModel
的onCancel()
方法,而后就有了监听ViewModel
取消时自动取消网络请求的想法。下面是具体实现:架构
//ViewModelEvent.kt
enum class ViewModelEvent {
ACTIVE,
CANCEL
}
复制代码
//RxLifecycleViewModel.kt
class RxLifecycleViewModel private constructor() {
init {
throw AssertionError("No instances")
}
companion object {
@CheckResult
fun <T> bindViewModel(lifecycle: Observable<ViewModelEvent>): LifecycleTransformer<T> {
return bind(lifecycle, VIEW_MODEL_LIFECYCLE)
}
// Figures out which corresponding next lifecycle event in which to unsubscribe, for ViewModels
private val VIEW_MODEL_LIFECYCLE = Function<ViewModelEvent, ViewModelEvent> { lastEvent ->
when (lastEvent) {
ViewModelEvent.ACTIVE -> ViewModelEvent.ACTIVE
ViewModelEvent.CANCEL -> throw OutsideLifecycleException("Cannot bind to view model lifecycle when outside of it.")
}
}
}
}
复制代码
//RxViewModel.kt
abstract class RxViewModel : ViewModel(), LifecycleProvider<ViewModelEvent> {
private val lifecycleSubject = BehaviorSubject.create<ViewModelEvent>().apply {
onNext(ViewModelEvent.ACTIVE)
}
override fun lifecycle(): Observable<ViewModelEvent> {
return lifecycleSubject.hide()
}
override fun <T : Any?> bindUntilEvent(event: ViewModelEvent): LifecycleTransformer<T> {
return RxLifecycle.bindUntilEvent<T, ViewModelEvent>(lifecycleSubject, event)
}
override fun <T : Any?> bindToLifecycle(): LifecycleTransformer<T> {
return RxLifecycleViewModel.bindViewModel(lifecycleSubject)
}
override fun onCleared() {
super.onCleared()
lifecycleSubject.onNext(ViewModelEvent.CANCEL)
}
}
复制代码
而后上面那段代码就能够改写成下面:app
class ExampleViewModel : RxViewModel() {
fun download(url: String) {
ExampleApi.getNetService()
.download(url)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(this.bindUtilEvent(ActivityEvent.Destroy))
.subscribe(object: Observer<ResponseBody> {
override fun onNext(responseBody: ResponseBody) {
//doSomething
}
override fun onSubscribe(d: Disposable) {
}
override fun onComplete() {
}
override fun onError(e: Throwable) {
}
})
}
}
复制代码