【问题标题】:Network Only Resource From Livedata To RxJava从 Livedata 到 RxJava 的仅网络资源
【发布时间】:2019-04-25 20:44:25
【问题描述】:

我有这个类使用 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>>

}

【问题讨论】:

  • 那么在 RxJava 中,它应该是什么?行为中继?

标签: android rx-java2 android-livedata


【解决方案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))

【讨论】:

  • 这个map(Utils::processResponse)是什么意思?
  • @Felipe A., .map(Utils::processResponse) 这一行应该将 ApiResponse 对象转换为 Resource 对象。 Utils::processResponse 是您需要实现的函数,它接受一个 ApiResponse 实例并返回一个 Resource 实例。
猜你喜欢
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 2022-10-04
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多