Как застегнуть две наблюдаемые в Android? - PullRequest
0 голосов
/ 14 февраля 2019

В моем приложении у меня есть две службы, и у каждой из них есть метод, который делает запросы, а затем возвращает Observable другого типа.

Я хочу отобразить в RecyclerView список, составленный из результата объединения этих двух наблюдаемых.Я гуглил об этом и нашел метод zip (), который, кажется, делает именно то, что я хочу.Я пытаюсь реализовать это, но я не знаю, как это сделать правильно.

Пока я гуглил, я придумал эту эту статью , которая, кажется, объясняет это ясно.Хотя автор использует Singles, а я использую Observables.

Насколько я понимаю, как работает zip(), я знаю, что должен передать каждое Observable, которое я хочу, "сжать", а затем я должен указать функцию, которая будет составлять мой последний Observable, верно?

Это мой код:

interface InvitationService {
    @GET("foo/{userId}")
    fun getFooByUser(@Path("userId") userId: String): Observable<Response<ArrayList<Foo>>>
}

interface InvitationService {
    @GET("bar/{userId}")
    fun getBarByUser(@Path("userId") userId: String): Observable<Response<ArrayList<Bar>>>
}

class FooRemoteDataSource : FooDataSource {
    private var apiService: FooService

    fun getFooByUser(userId:String) {
        return apiService.getFooByUser(userId)
    }
}

class BarRemoteDataSource : BarDataSource {
    private var apiService: BarService

    fun getBarByUser(userId:String) {
        return apiService.getBarByUser(userId)
    }

}

class FooRepository(private val remoteDataSource: InvitationRemoteDataSource) : FooDataSource {

    override fun getFooByUser(userId: String): Observable<Response<ArrayList<Foo>>> {
        return remoteDataSource.getFooByUser(userId)
    }
}

class BarRepository(private val remoteDataSource: BarRemoteDataSource) : BarDataSource {

    override fun getBarByUser(userId: String): Observable<Response<ArrayList<Bar>>> {
        return remoteDataSource.getBarByUser(userId)
    }
}

И вот где я на самом деле застрял:

class ListPresenter(var listFragment: ListContract.View?, 
                        val fooRepository: FooRepository,
                        val barRepository: BarRepository) : ListContract.Presenter {

    fun start() {
        loadList()
    }

    private fun loadLists() {
        //HERE IS WHERE IM STUCK

        Observable.zip(fooRepository.getFooByUser(userId).subscribeOn(Schedulers.io()),
                barRepository.getBarByUser(userId).subscribeOn(Schedulers.io()),
                )

        // AFTER 'ZIPPING' THE OBSERVABLES 
        // I NEED TO UPDATE THE VIEW ACCORDINGLY
    }
}

Я не знаю, как правильно вызвать zip()Я знаю, что должен передать функцию, но не получаю ее, потому что в статье, указанной выше, автор использует Function3, потому что у него есть 3 Observables.

Поскольку у меня только 2, я не знаю, как это сделать.Если открывать фигурные скобки после запятой внутри аргумента метода, требуется, чтобы я возвратил BiFunction<ArrayList<Foo>, ArrayList<Bar>>, что я не знаю, как указать.

Кто-нибудь объяснит мне это?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Архивирование двух наблюдаемых различных типов с использованием BiFunction

override fun getCommoditiesAndAddresses() {
    view.showProgress()
    view.hideViews()
    Observable.zip(Commo24Retrofit.createAuthService(RateAPIService::class.java)
            .getCommodities(),
            Commo24Retrofit.createAuthService(RateAPIService::class.java)
                    .getLocations(GetLocationsRequest(getOrgId())),
            BiFunction { commodityResponse: GetCommoditiesResponse, locationsResponse: GetLocationsResponse ->
                handleCommoditiesAndAddresses(commodityResponse, locationsResponse)
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                view.hideProgress()
                view.showViews()
                view.handleCommodities(it?.commodities)
                view.handleLocations(it?.locations)
            }, { throwable ->
                view.hideProgress()
                view.handleFailure(throwable.getErrorMessage(context))
            })
}

Посмотрите, как я обрабатываю ответ:

private fun handleCommoditiesAndAddresses(commodityResponse: GetCommoditiesResponse, locationsResponse: GetLocationsResponse): CommoditiesAddresses {
        return CommoditiesAddresses(commodityResponse.commodityList, locationsResponse.addressList)
    }

Здесь, проверьте APIСлужба:

interface RateAPIService {

    @POST("get-org-address")
    fun getLocations(@Body getLocationsRequest: GetLocationsRequest): Observable<GetLocationsResponse>

    @POST("get-commodity-list")
    fun getCommodities(): Observable<GetCommoditiesResponse>
    }

Если у вас есть какие-либо сомнения, вы можете их закомментировать.

0 голосов
/ 14 февраля 2019

Для Kotlin вы должны использовать RxKotlin вместо RxJava.BiFunction, Function3 происходят из RxJava.С RxKotlin вы можете вместо этого использовать лямбды.


Насколько я понимаю, как работает zip (), я знаю, что должен передать каждое Observable, которое я хочу, "zip", а затем я должен указатьфункция, которая будет составлять мой последний Observable, верно?

Правильно, и вот минимальный пример, который демонстрирует, как это сделать.

Пример 1

val observable1 = listOf(1, 2, 3).toObservable()
val observable2 = listOf(4, 5, 6).toObservable()
val zipped = Observables.zip(observable1, observable2) { o1, o2 -> o1 * o2}

В этом примере у вас есть две наблюдаемые, каждая из которых испускает целые числа.Вы передаете их zip и в качестве третьего аргумента лямбда, которая определяет способ их «объединить».В этом случае он умножает их.

Полученная наблюдаемая zipped выдаст: 4, 10 и 18.


Пример 2

Вот еще один пример, который упаковывает три наблюдаемые, которые не все одного типа:

val obs1 = listOf("on", "tw", "thre").toObservable()
val obs2 = listOf("n", "o", "e").toObservable()
val obs3 = listOf(1, 2, 3).toObservable()
val zipped = Observables.zip(obs1, obs2, obs3) { o1, o2, o3 -> 
    "$o1$o2 = $o3"
}

Здесь каждый элемент результирующей наблюдаемой будет строкой: «one = 1», «two = 2»,"три = 3"

...