Skip to content

Commit

Permalink
Switch to event-based implementation
Browse files Browse the repository at this point in the history
WIP still as I don't really know how to test this nicely
  • Loading branch information
ZacSweers committed Aug 20, 2017
1 parent c3045b5 commit aa1e6b2
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,55 +17,87 @@
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<State> {
class LifecycleEventsObservable extends Observable<Event> {

private final Lifecycle lifecycle;
private final BehaviorSubject<Event> 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<? super State> observer) {
if (!AutoDisposeAndroidUtil.isMainThread()) {
Event getValue() {
return eventsObservable.getValue();
}

@Override protected void subscribeActual(Observer<? super Event> 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);
}

static final class ArchLifecycleObserver extends MainThreadDisposable
implements LifecycleObserver {
private final Lifecycle lifecycle;
private final Observer<? super State> observer;
private final Observer<? super Event> observer;
private final BehaviorSubject<Event> eventsObservable;

ArchLifecycleObserver(Lifecycle lifecycle, Observer<? super State> observer) {
ArchLifecycleObserver(Lifecycle lifecycle, Observer<? super Event> observer,
BehaviorSubject<Event> 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);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* <pre><code>
* AutoDispose.observable()
* .scopeWith(LifecycleOwnerScopeProvider.from(view))
* .empty();
* myFooObservable
* .to(new ObservableScoper<Foo>(LifecycleOwnerScopeProvider.from(lifecycleOwner)))
* .subscribe();
* </code></pre>
*/
public final class LifecycleOwnerScopeProvider implements LifecycleScopeProvider<Lifecycle.State> {
public final class LifecycleOwnerScopeProvider implements LifecycleScopeProvider<Lifecycle.Event> {

private static final Function<Lifecycle.State, Lifecycle.State> CORRESPONDING_EVENTS =
new Function<Lifecycle.State, Lifecycle.State>() {
@Override public Lifecycle.State apply(Lifecycle.State lastEvent) throws Exception {
private static final Function<Lifecycle.Event, Lifecycle.Event> CORRESPONDING_EVENTS =
new Function<Lifecycle.Event, Lifecycle.Event>() {
@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();
}
Expand All @@ -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.State> lifecycle() {
@Override public Observable<Lifecycle.Event> lifecycle() {
return lifecycleObservable;
}

@Override public Function<Lifecycle.State, Lifecycle.State> correspondingEvents() {
@Override public Function<Lifecycle.Event, Lifecycle.Event> correspondingEvents() {
return CORRESPONDING_EVENTS;
}

@Override public Lifecycle.State peekLifecycle() {
return lifecycle.getCurrentState();
@Override public Lifecycle.Event peekLifecycle() {
return lifecycleObservable.getValue();
}
}

0 comments on commit aa1e6b2

Please sign in to comment.