Только сетевой ресурс из Livedata в RxJava - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть этот класс, который делает запрос вызова с liveata ... Я хочу преобразовать этот класс в класс rxjava ... Потому что я хочу использовать rxjava в моих классах репозитория / viewmodel ...

Может кто-нибудь помочь мне сделать это чаги, пожалуйста?

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 Ответ

1 голос
/ 27 апреля 2019

Ответ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). Вам не понадобятся сложные классы, ни все эти MediatorLivedata и Transformer shenanigans с RxJava.

Например, класс 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))
...