Когда удалять RxJava2 Disposable в ViewModel?

Я использую ViewModel из компонентов архитектуры Android в своем приложении. В ViewModel я использую подписку RxJava2 и сохраняю Disposable объект после подписки. Раньше, когда я делал это в Activity, я использовал для удаления Disposable в onDestroy() - чтобы избежать утечек памяти:

@Override
protected void onDestroy() {
    disposable.dispose();
    super.onDestroy();
}

Когда и как я должен утилизировать его в ViewModel? Мне действительно нужно это делать?


person Micer    schedule 01.04.2018    source источник


Ответы (2)


с методом onCleared

@Override
protected void onCleared () {
    disposable.dispose();
    super.onCleared ();
}
person Samuel Eminet    schedule 01.04.2018
comment
Этот метод вызывается только тогда, когда активность появляется из заднего стека. Этот ведущий поток данных не удаляется, когда вы открываете второе действие, а первое действие помещается в задний стек. - person XIII-th; 21.09.2018
comment
@Sergey Ваша активность может быть уничтожена в любое время, когда она все равно попадает в фоновый режим, в то время как ваша активность не уничтожается, в большинстве случаев вы, конечно, не хотите убивать свои потоки данных, иначе, если активность вернется на передний план до того, как будет уничтожена, все ваши потоки будут убит, и, таким образом, ваша активность будет десинхронизирована с вашими данными - person Samuel Eminet; 21.09.2018
comment
Я обнаружил, что мне нужно очищать одноразовые предметы в 2 местах: 1) в oncleared, как указано выше, а также 2) в методе ondestroyview моих фрагментов. ›› Если я не очищаю одноразовые предметы в соответствии с пунктом 1), то мой подписчик срабатывает, когда контекст становится нулевым после выхода из представления, и приложение аварийно завершает работу. Если я не очищаю в соответствии с пунктом 2), то у меня возникают проблемы с утечкой памяти, которые, например, вызывали прерывистость моих прослушивателей кликов после обратной навигации. - person Rowan Gontier; 06.03.2020
comment
@RowanGontier Я никогда не использовал rx на стороне контроллера (фрагменты), я использую rx только из модели представления и livedata на стороне контроллера, LiveDataReactiveStreams # fromPublisher может быть полезен для преобразования rx в livedata. Таким образом, вам не нужно распоряжаться на стороне контроллера - person Samuel Eminet; 06.03.2020

Вы можете использовать LiveDataReactiveStreams#fromPublisher(Publisher<T>) и предоставить результат LiveData из модели представления вместо подписки и удаления в модели представления.

Например:

public class ExampleViewModel {

    private static final long TIME_FOR_ANSWER = 1000;
    private static final long DELAY = 25;

    private final LiveData<Long> remainingTime;

    ExampleViewModel() {
        long start = 0;
        long count = TIME_FOR_ANSWER / DELAY + 1;
        Flowable<Long> flowable =
              Flowable.intervalRange(start, count, 0, DELAY, TimeUnit.MILLISECONDS)
                      .map(i -> TIME_FOR_ANSWER - DELAY * i);
        remainingTime = LiveDataReactiveStreams.fromPublisher(flowable);
    }

    public LiveData<Long> getRemainingTime() {
        return remainingTime;
    }
}
person arekolek    schedule 04.04.2018
comment
Что я на самом деле делаю, так это использую Observable.timer здесь. Не могли бы вы посоветовать мне, как использовать его с LiveDataReactiveStreams? Вот код: gist.github.com/micer/93b02625bd078e52c5258eabaaea4449 - person Micer; 04.04.2018
comment
Кроме того, вот как обрабатывать ротацию: stackoverflow.com/q/47382786/1916449 - person arekolek; 04.04.2018
comment
эй, когда мы используем LiveDataReactiveStreams, он обрабатывает Rx Observation так же, как CompositDisposable? - person Yasin Hajilou; 19.06.2020
comment
@yasin Не уверен, что вы имеете в виду, может быть, вы можете опубликовать это как отдельный вопрос и немного уточнить? - person arekolek; 20.06.2020