Created
October 9, 2017 16:19
-
-
Save amaksoft/bb6575e6d5ca081ea81b975dc6497598 to your computer and use it in GitHub Desktop.
RxJava2 Disposable bound to Activity/Fragment lifecycle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.amaksoft.tools; | |
import android.arch.lifecycle.Lifecycle; | |
import android.arch.lifecycle.LifecycleObserver; | |
import android.arch.lifecycle.LifecycleOwner; | |
import android.arch.lifecycle.OnLifecycleEvent; | |
import io.reactivex.disposables.Disposable; | |
/** | |
* Обертка для {@link Disposable}, автоматически отписывающаяся в onDestroy() или другой заданный | |
* коллбек жизненного цикла соотествующих активити и фрагментов. | |
* При попытке подписаться в уничтоженном фрагменте отпишется сразу в момент вызова | |
* метода {@link #create(LifecycleOwner, Lifecycle.Event, Disposable)} | |
* @author Andrey Makeev | |
*/ | |
public class AndroidDisposable implements LifecycleObserver, Disposable { | |
private Disposable disposable; | |
private Lifecycle.Event disposeEvent; | |
// Приватный конструктор т.к. есть factory-метод | |
private AndroidDisposable() {} | |
/** | |
* Метод для создания автоотписывающегося {@link Disposable} (отписывается в onDestroy) | |
* @param owner {@link LifecycleOwner}, к жизненному циклу которого привязывается {@link Disposable} | |
* @param disposable {@link Disposable}, от которого нужно отписываться при закрытии экрана | |
* @return ссылка на объект {@link AndroidDisposable} | |
*/ | |
public static AndroidDisposable create(LifecycleOwner owner, Disposable disposable) { | |
return create(owner, Lifecycle.Event.ON_DESTROY, disposable); | |
} | |
/** | |
* Метод для создания автоотписывающегося {@link Disposable} (отписывается при заданном событии) | |
* @param owner {@link LifecycleOwner}, к жизненному циклу которого привязывается {@link Disposable} | |
* @param disposable {@link Disposable}, от которого нужно отписываться при закрытии экрана | |
* @param disposeEvent {@link android.arch.lifecycle.Lifecycle.Event} при котором нужно отписаться | |
* @return ссылка на объект {@link AndroidDisposable} | |
*/ | |
public static AndroidDisposable create(LifecycleOwner owner, Lifecycle.Event disposeEvent, Disposable disposable) { | |
AndroidDisposable androidDisposable = new AndroidDisposable(); | |
androidDisposable.disposable = disposable; | |
androidDisposable.disposeEvent = disposeEvent; | |
boolean destroyed = !owner.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED); | |
if (destroyed) { | |
androidDisposable.dispose(); // если фрагмент/активити уже уничтожены, отписываемся в момент создания | |
} else { | |
owner.getLifecycle().addObserver(androidDisposable); // если не уничтожены - подписываемся на коллбеки lifecycle | |
} | |
return androidDisposable; | |
} | |
/* | |
* Имплементация метода автоматической отписки | |
*/ | |
@SuppressWarnings({"WeakerAccess", "unused"}) | |
@OnLifecycleEvent(Lifecycle.Event.ON_ANY) | |
void onStateChange(LifecycleOwner owner, Lifecycle.Event event) { | |
// Если event == заданное событие для отписки - отписываемся | |
// Если LifecycleOwner в состоянии DESTROYED - отписываемся в любом случае | |
if (event == disposeEvent || owner.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) { | |
dispose(); | |
owner.getLifecycle().removeObserver(this); | |
} | |
} | |
/** | |
* Метод для отписки аналогично {@link Disposable#dispose()} | |
*/ | |
@Override | |
public void dispose() { | |
if (!isDisposed()) { | |
disposable.dispose(); | |
disposable = null; | |
} | |
} | |
/** | |
* Метод для проверки статуса подписки аналогично {@link Disposable#isDisposed()} | |
* @return статус подписки | |
*/ | |
@Override | |
public boolean isDisposed() { | |
return disposable == null || disposable.isDisposed(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment