diff --git a/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleStatesObservable.java b/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleEventsObservable.java similarity index 51% rename from autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleStatesObservable.java rename to autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleEventsObservable.java index 986af6e7b..d0adbd628 100644 --- a/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleStatesObservable.java +++ b/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleEventsObservable.java @@ -17,34 +17,62 @@ package com.uber.autodispose.android.archcomponents; import android.arch.lifecycle.Lifecycle; -import android.arch.lifecycle.Lifecycle.State; +import android.arch.lifecycle.Lifecycle.Event; import android.arch.lifecycle.LifecycleObserver; +import android.arch.lifecycle.LifecycleOwner; import android.arch.lifecycle.OnLifecycleEvent; import android.support.annotation.RestrictTo; import com.uber.autodispose.android.internal.AutoDisposeAndroidUtil; import io.reactivex.Observable; import io.reactivex.Observer; import io.reactivex.android.MainThreadDisposable; +import io.reactivex.subjects.BehaviorSubject; import static android.support.annotation.RestrictTo.Scope.LIBRARY; +import static com.uber.autodispose.android.internal.AutoDisposeAndroidUtil.isMainThread; @RestrictTo(LIBRARY) -class LifecycleStatesObservable extends Observable { +class LifecycleEventsObservable extends Observable { private final Lifecycle lifecycle; + private final BehaviorSubject eventsObservable = BehaviorSubject.create(); - LifecycleStatesObservable(Lifecycle lifecycle) { + @SuppressWarnings("CheckReturnValue") LifecycleEventsObservable(Lifecycle lifecycle) { this.lifecycle = lifecycle; + // Backfill if already created for boundary checking + Lifecycle.State currentState = lifecycle.getCurrentState(); + if (currentState.isAtLeast(Lifecycle.State.CREATED)) { + Event event; + switch (lifecycle.getCurrentState()) { + case CREATED: + event = Event.ON_CREATE; + break; + case STARTED: + event = Event.ON_START; + break; + case RESUMED: + event = Event.ON_RESUME; + break; + default: + event = Event.ON_DESTROY; + break; + } + eventsObservable.onNext(event); + } } - @Override protected void subscribeActual(Observer observer) { - if (!AutoDisposeAndroidUtil.isMainThread()) { + Event getValue() { + return eventsObservable.getValue(); + } + + @Override protected void subscribeActual(Observer observer) { + if (!isMainThread()) { observer.onError( new IllegalStateException("Lifecycles can only be bound to on the main thread!")); return; } - - ArchLifecycleObserver archObserver = new ArchLifecycleObserver(lifecycle, observer); + ArchLifecycleObserver archObserver = + new ArchLifecycleObserver(lifecycle, observer, eventsObservable); observer.onSubscribe(archObserver); lifecycle.addObserver(archObserver); } @@ -52,20 +80,24 @@ class LifecycleStatesObservable extends Observable { static final class ArchLifecycleObserver extends MainThreadDisposable implements LifecycleObserver { private final Lifecycle lifecycle; - private final Observer observer; + private final Observer observer; + private final BehaviorSubject eventsObservable; - ArchLifecycleObserver(Lifecycle lifecycle, Observer observer) { + ArchLifecycleObserver(Lifecycle lifecycle, Observer observer, + BehaviorSubject eventsObservable) { this.lifecycle = lifecycle; this.observer = observer; + this.eventsObservable = eventsObservable; } @Override protected void onDispose() { lifecycle.removeObserver(this); } - @OnLifecycleEvent(Lifecycle.Event.ON_ANY) void onStateChange() { + @OnLifecycleEvent(Event.ON_ANY) void onStateChange(LifecycleOwner owner, Event event) { if (!isDisposed()) { - observer.onNext(lifecycle.getCurrentState()); + eventsObservable.onNext(event); + observer.onNext(event); } } } diff --git a/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleOwnerScopeProvider.java b/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleOwnerScopeProvider.java index 5440b0e18..c050d0a37 100644 --- a/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleOwnerScopeProvider.java +++ b/autodispose-android-archcomponents/src/main/java/com/uber/autodispose/android/archcomponents/LifecycleOwnerScopeProvider.java @@ -19,37 +19,37 @@ import android.arch.lifecycle.Lifecycle; import android.arch.lifecycle.LifecycleOwner; import com.uber.autodispose.LifecycleEndedException; -import com.uber.autodispose.LifecycleNotStartedException; import com.uber.autodispose.LifecycleScopeProvider; import io.reactivex.Observable; import io.reactivex.functions.Function; -import static android.arch.lifecycle.Lifecycle.State.DESTROYED; - /** - * A {@link LifecycleScopeProvider} that can provide scoping for Android - * {@link LifecycleOwner} classes. + * A {@link LifecycleScopeProvider} that can provide scoping for Android {@link LifecycleOwner} + * classes. *

*


- *   AutoDispose.observable()
- *      .scopeWith(LifecycleOwnerScopeProvider.from(view))
- *      .empty();
+ *   myFooObservable
+ *      .to(new ObservableScoper(LifecycleOwnerScopeProvider.from(lifecycleOwner)))
+ *      .subscribe();
  * 
*/ -public final class LifecycleOwnerScopeProvider implements LifecycleScopeProvider { +public final class LifecycleOwnerScopeProvider implements LifecycleScopeProvider { - private static final Function CORRESPONDING_EVENTS = - new Function() { - @Override public Lifecycle.State apply(Lifecycle.State lastEvent) throws Exception { + private static final Function CORRESPONDING_EVENTS = + new Function() { + @Override public Lifecycle.Event apply(Lifecycle.Event lastEvent) throws Exception { switch (lastEvent) { - case INITIALIZED: - throw new LifecycleNotStartedException(); - case CREATED: - return DESTROYED; - case STARTED: - return DESTROYED; - case RESUMED: - return DESTROYED; + case ON_CREATE: + return Lifecycle.Event.ON_DESTROY; + case ON_START: + return Lifecycle.Event.ON_STOP; + case ON_RESUME: + return Lifecycle.Event.ON_PAUSE; + case ON_PAUSE: + return Lifecycle.Event.ON_STOP; + case ON_STOP: + return Lifecycle.Event.ON_DESTROY; + case ON_DESTROY: default: throw new LifecycleEndedException(); } @@ -73,26 +73,25 @@ public static LifecycleOwnerScopeProvider from(LifecycleOwner owner) { * @return a {@link LifecycleOwnerScopeProvider} against this lifecycle. */ public static LifecycleOwnerScopeProvider from(Lifecycle lifecycle) { + return new LifecycleOwnerScopeProvider(lifecycle); } - private final Lifecycle lifecycle; - private final LifecycleStatesObservable lifecycleObservable; + private final LifecycleEventsObservable lifecycleObservable; private LifecycleOwnerScopeProvider(Lifecycle lifecycle) { - this.lifecycle = lifecycle; - this.lifecycleObservable = new LifecycleStatesObservable(lifecycle); + this.lifecycleObservable = new LifecycleEventsObservable(lifecycle); } - @Override public Observable lifecycle() { + @Override public Observable lifecycle() { return lifecycleObservable; } - @Override public Function correspondingEvents() { + @Override public Function correspondingEvents() { return CORRESPONDING_EVENTS; } - @Override public Lifecycle.State peekLifecycle() { - return lifecycle.getCurrentState(); + @Override public Lifecycle.Event peekLifecycle() { + return lifecycleObservable.getValue(); } }