从Livedata到RxJava的仅网络资源

时间:2019-04-25 20:44:25

标签: android rx-java2 android-livedata

我有一个使用livedata进行请求调用的类...我想将该类转换为rxjava类...因为我想在我的存储库/ viewmodel类上使用rxjava ...

有人可以帮我做些麻烦吗?

abstract class NetworkOnlyResource<RequestType> {

private val result = MediatorLiveData<Resource<RequestType>>()

init {
    result.value = Resource.loading(null)
    fetchFromNetwork()
}

@MainThread
private fun setValue(newValue: Resource<RequestType>) {
    if (result.value != newValue) {
        result.value = newValue
    }
}

private fun fetchFromNetwork() {
    val apiResponse = createCall()
    result.addSource(apiResponse) { response ->
        result.removeSource(apiResponse)

        when (response) {
            is ApiSuccessResponse -> {
                setValue(Resource.success(processResponse(response)))
            }

            is ApiEmptyResponse -> {
                setValue(Resource.success(null))
            }

            is ApiErrorResponse -> {
                onFetchFailed()
                setValue(Resource.error(response.errorMessage, null))
            }
        }
    }
}

protected open fun onFetchFailed() {}

fun asLiveData() = result as LiveData<Resource<RequestType>>

@WorkerThread
protected open fun processResponse(response: ApiSuccessResponse<RequestType>) = response.body

@MainThread
protected abstract fun createCall(): LiveData<ApiResponse<RequestType>>

}

1 个答案:

答案 0 :(得分:1)

答案1

如果您想“将此类转换为rxjava类”,则可能会执行以下操作:

abstract class RxNetworkOnlyResource<RequestType> {
     private val result = BehaviorSubject.create<Resource<RequestType>>()

     init {
         createCall()
             .toObservable()
             .map { response ->
                 when (response) {
                     is ApiSuccessResponse -> {
                         Resource.success(processResponse(response))
                     }

                     is ApiEmptyResponse -> {
                         Resource.success(null)
                     }

                     is ApiErrorResponse -> {
                         onFetchFailed()
                         Resource.error(response.errorMessage, null)
                     }
                 }
             }
             .startWith(Resource.loading(null))
             .subscribe(result)
     }

     protected open fun onFetchFailed() {}

     fun asObservable() = result as Observable<Resource<RequestType>>

     protected open fun processResponse(response: ApiSuccessResponse<RequestType>) = response.body         

     protected abstract fun createCall(): Single<ApiResponse<RequestType>>
}

BehaviorRelay可能更有意义,但是BehaviorSubject在您的特定情况下可能会正常工作。


答案2

我建议您摆脱此类(与尝试转换为RxJava相对)。您将不需要复杂的类,也不需要所有这些带有RxJava的MediatorLivedata和Transformer恶作剧。

例如,您拥有的LiveData类可以像这样使用:

object: NetworkOnlyResource<RequestType>() {
    override fun createCall(): LiveData<ApiResponse<RequestType>> {
        return someCall()
    }
}.asLiveData() // This returns LiveData<Resource<RequestType>> instance

除了拥有此类NetworkOnlyResource之外,您还可以执行以下操作:

someCall().toObservable()
    .map(Utils::processResponse)
    .startWith(Resource.loading(null))