RxJava повторно подписывается на событие после восстановления активности

Я все еще разбираюсь в RxJava и использую его, чтобы сделать некоторые сетевые вещи с помощью Retrofit 2. Пробовал это в течение пары дней, и вот этот код выглядит более читаемым, но натолкнулся на проблему, рисуйте путь вокруг.

Я пытаюсь выполнить логин (который возвращает токен API), а затем использовать этот токен для извлечения некоторых исходных данных в одной и той же цепочке, так что вывод цепочки - это токены + данные. Для этого я вызываю службу API с помощью

apiClient
    .login()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(token -> getData(token))
    .subscribe(new Subscrber<Bundle>() {...});

Это казалось прекрасным, но я также хотел показать индикатор выполнения при запуске и остановке цепочки. Поэтому я добавил в это .doOnSubscribe() и .doOnUnsubscribe(). Однако я заметил, что после изменения ориентации фрагмент, который я пытался скрыть индикатор выполнения, всегда равен нулю.

Итак, я обыскал и наткнулся на RxLifecycle lib, который, казалось, помог, и теперь я .cache() и отпишусь от события цепь. Но я не могу понять, как подписаться на одно и то же событие снова в onCreate() после этого? Я думаю, что я пропустил что-то довольно простое и буду признателен за любую помощь в этом.

Ответы

Ответ 1

Для этого вам необязательно использовать любой шаблон архитектуры. Несмотря на то, что любой MVP/MVC - это приятные вещи для решения проблем разделения, тестирования и т.д., Что делает ваш контроллер/презентатор/DAO одним сингл-узлом, который поддерживает память через весь срок службы приложений, не совсем хорошая идея.

Здесь пример проекта с использованием экземпляра оставшегося фрагмента и RxJava - https://github.com/krpiotrek/RetainFragmentSample

Основная идея заключается в том, чтобы использовать фрагмент с вызванным setRetainInstance (true), который защищает его от разрушения при изменении ориентации и сохраняет там Наблюдаемый. Вот как вы справляетесь с этим в Activity/Fragment onCreate

protected void onCreate(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        // first run, create observable
        mInfoObservable = createInfoObservable();
        // set Observable in retained fragment
        RetainFragmentHelper.setObject(this, getSupportFragmentManager(), mInfoObservable);
    } else {
        // following runs, get observable from retained fragment
        mInfoObservable = RetainFragmentHelper.getObjectOrNull(this, getSupportFragmentManager());
    }

    // subscribe 
    mInfoObservable.subscribe(...);
}

Имейте в виду, что ваш Observable должен кэшировать последнее значение, одним из способов является использование оператора cache().

Ответ 2

Вам нужно убедиться, что вы подписаны на тот же Observable экземпляр, который возвращается с .cache(). Обычно вы храните этот экземпляр где-то в Singleton (например, в классе Application), в сохраненном фрагменте или в Android-сервисе.