公司項目中的網絡請求是用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) {
}
})
}
}
複製代碼