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-сервисе.