Rx Java с LiveData: как заставить Flowable вести себя как BehaviorProcessor - PullRequest
0 голосов
/ 02 августа 2020

У меня возникла проблема с Android, RxJava2 и LiveData после остановки и возобновления фрагмента. Я хочу поделиться своим решением и попросить лучшее.

После некоторого расследования я смог сократить проблему до модульного теста. Есть способ пройти этот тест, если я добавлю .replay(1).autoConnect() перед преобразованием Flowable в LiveData. Обратной стороной этого решения является то, что я не могу использовать switchMap после combineLatest, потому что это приведет к утечке его подписчиков.

import androidx.annotation.NonNull;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.LiveDataReactiveStreams;

import org.junit.Rule;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import io.reactivex.Flowable;
import io.reactivex.processors.PublishProcessor;

import static org.junit.Assert.assertEquals;

public class CombineLatestResumeTest implements LifecycleOwner {

    @Rule
    public InstantTaskExecutorRule rule = new InstantTaskExecutorRule();

    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);

    @Test
    public void resume() {
        PublishProcessor<String> animals = PublishProcessor.create();
        PublishProcessor<String> fruits = PublishProcessor.create();

        Flowable<String> result = Flowable.combineLatest(animals, fruits, (a, b) -> String.format("%s likes %s", a, b));
        LiveData<String> stringLiveData = LiveDataReactiveStreams.fromPublisher(result);

        List<String> values = new ArrayList<>();
        stringLiveData.observe(this, values::add);

        lifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED);

        animals.onNext("?");
        fruits.onNext("?");

        lifecycleRegistry.setCurrentState(Lifecycle.State.CREATED);
        lifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED);

        animals.onNext("?");
        assertEquals(Arrays.asList("? likes ?", "? likes ?"), values);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return lifecycleRegistry;
    }
}

Можно ли заставить switchMap работать после повторной подписки LiveData ?

...