Rx Java Одиночная фильтрация списка внутри объекта и возврат его объекта с отфильтрованным списком - PullRequest
0 голосов
/ 01 мая 2020

Я использую RxJava2 (Single) с модификацией для сетевых запросов, при получении ответа, меняю другие поля, которые содержит объект, есть список объектов, что я пытаюсь достичь, это отфильтровать объекты (в списке ), который содержит определенный 'id', и я хочу, чтобы это происходило в фоновом потоке, а затем отправлял ответ после того, как объект отфильтровал свой список.

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

1 Ответ

0 голосов
/ 02 мая 2020

Предварительное условие

implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")

API

data class Result(val id: Int)

data class MyObject(val values: List<Result> = emptyList())

interface RetroFitApi {
    fun getAll(): Single<MyObject>
}

internal class RetroFitApiImpl : RetroFitApi {
    override fun getAll(): Single<MyObject> {
        return Single.fromCallable {
            MyObject(
                listOf(Result(1), Result(2), Result(3))
            )
        }
    }
}

Использование при модификации, когда у Retrofit нет собственной модели потоков (androidTest)

import android.os.Looper
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import java.util.concurrent.TimeUnit 

@Test
internal fun name() {
    val api = RetroFitApiImpl()

    val test = api.getAll()
        // make sure the subscribe lambda is called in background-thread
        .subscribeOn(Schedulers.io())
        .map { result ->
            // remove all elements, which are id == 1
            result.copy(values = result.values.filterNot { it.id == 1 })
        }
        // move emit, which will probably be emitted from Schedules#io-Thread to Main-Loop. Therefore after applying observeOn the onNext emit in subscribe will be emitted on the UI-Android-Loop
        .observeOn(AndroidSchedulers.mainThread())
        .test()

    test.awaitDone(500, TimeUnit.MILLISECONDS)

    assertThat(test.lastThread()).isEqualTo(Looper.getMainLooper().thread)

    assertThat(test.values()).containsExactly(
        MyObject(values = listOf(Result(2), Result(3)))
    )
}

Относительно

вне зоны действия: есть ли способ, которым я могу определить в каждом операторе, какой поток использует? последний звонил. Вы не можете знать, в каком потоке будет генерироваться onNext во время выполнения, потому что Rx Java вообще не заботится о потоке, только если вы возьмете его в свои руки с помощью visibleOn / subscribeOn. По умолчанию onNext будет вызываться в вызывающем потоке. Если вызывающий поток аналогичен подписывающему, ваш результат будет (вероятно) генерироваться синхронно, если не задействовано ни одного потока.

Дальнейшее чтение:

http://tomstechnicalblog.blogspot.com/2016/02/rxjava-understanding-observeon-and.html

...