照葫芦画瓢写RxViewModel

​ 公司项目中的网络请求是用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中的方法传入ActivityFragment实例,而后又须要某些网络请求在ActivityFragment销毁时取消请求来释放资源。看了ViewModelRxLifeCycle源码以后,发现Activity或者Fragment会在destroy时调用VIewModelonCancel()方法,而后就有了监听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) {

                    }
            })
    }
    
}
复制代码
相关文章
相关标签/搜索