Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make AndroidLifecycleScopeProvider reusable by deferring backfill to peekLifecycle #121

Merged
merged 3 commits into from
Oct 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public final class AndroidLifecycleScopeProvider
case ON_STOP:
case ON_DESTROY:
default:
throw new LifecycleEndedException();
throw new LifecycleEndedException("Lifecycle has ended! Last event was " + lastEvent);
}
}
};
Expand Down Expand Up @@ -145,6 +145,7 @@ private AndroidLifecycleScopeProvider(Lifecycle lifecycle,
}

@Override public Lifecycle.Event peekLifecycle() {
lifecycleObservable.backfillEvents();
return lifecycleObservable.getValue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
import io.reactivex.android.MainThreadDisposable;
import io.reactivex.subjects.BehaviorSubject;

import static android.arch.lifecycle.Lifecycle.Event.ON_CREATE;
import static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY;
import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
import static android.arch.lifecycle.Lifecycle.Event.ON_START;
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
import static com.uber.autodispose.android.internal.AutoDisposeAndroidUtil.isMainThread;

Expand All @@ -38,33 +42,38 @@

@SuppressWarnings("CheckReturnValue") LifecycleEventsObservable(Lifecycle lifecycle) {
this.lifecycle = lifecycle;
// Backfill if already created for boundary checking
// We do a trick here for corresponding events where we pretend something is created
// upon initialized state so that it assumes the corresponding event is DESTROY.
@Nullable Event correspondingEvent;
}

Event getValue() {
return eventsObservable.getValue();
}

/**
* Backfill if already created for boundary checking. We do a trick here for corresponding events
* where we pretend something is created upon initialized state so that it assumes the
* corresponding event is DESTROY.
*/
void backfillEvents() {
@Nullable Lifecycle.Event correspondingEvent;
switch (lifecycle.getCurrentState()) {
case INITIALIZED:
correspondingEvent = Event.ON_CREATE;
correspondingEvent = ON_CREATE;
break;
case CREATED:
correspondingEvent = Event.ON_START;
correspondingEvent = ON_START;
break;
case STARTED:
case RESUMED:
correspondingEvent = Event.ON_RESUME;
correspondingEvent = ON_RESUME;
break;
case DESTROYED:
default:
correspondingEvent = Event.ON_DESTROY;
correspondingEvent = ON_DESTROY;
break;
}
eventsObservable.onNext(correspondingEvent);
}

Event getValue() {
return eventsObservable.getValue();
}

@Override protected void subscribeActual(Observer<? super Event> observer) {
if (!isMainThread()) {
observer.onError(
Expand Down Expand Up @@ -96,8 +105,8 @@ static final class ArchLifecycleObserver extends MainThreadDisposable

@OnLifecycleEvent(Event.ON_ANY) void onStateChange(LifecycleOwner owner, Event event) {
if (!isDisposed()) {
if (!(event == Event.ON_CREATE && eventsObservable.getValue() == event)) {
// Due to the INITIALIZED->ON_CREATE mapping trick we do in the constructor backfill,
if (!(event == ON_CREATE && eventsObservable.getValue() == event)) {
// Due to the INITIALIZED->ON_CREATE mapping trick we do in backfill(),
// we fire this conditionally to avoid duplicate CREATE events.
eventsObservable.onNext(event);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import java.util.concurrent.TimeUnit
*/
class KotlinActivity : AppCompatActivity() {

// Can be reused
private val scopeProvider by lazy { AndroidLifecycleScopeProvider.from(this) }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate()")
Expand All @@ -41,7 +44,7 @@ class KotlinActivity : AppCompatActivity() {
// dispose is onDestroy (the opposite of onCreate).
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose { Log.i(TAG, "Disposing subscription from onCreate()") }
.autoDisposeWith(AndroidLifecycleScopeProvider.from(this))
.autoDisposeWith(scopeProvider)
.subscribe { num -> Log.i(TAG, "Started in onCreate(), running until onDestroy(): " + num) }
}

Expand All @@ -54,7 +57,7 @@ class KotlinActivity : AppCompatActivity() {
// dispose is onStop (the opposite of onStart).
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose { Log.i(TAG, "Disposing subscription from onStart()") }
.autoDisposeWith(AndroidLifecycleScopeProvider.from(this))
.autoDisposeWith(scopeProvider)
.subscribe { num -> Log.i(TAG, "Started in onStart(), running until in onStop(): " + num) }
}

Expand All @@ -67,7 +70,7 @@ class KotlinActivity : AppCompatActivity() {
// dispose is onPause (the opposite of onResume).
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose { Log.i(TAG, "Disposing subscription from onResume()") }
.autoDisposeWith(AndroidLifecycleScopeProvider.from(this))
.autoDisposeWith(scopeProvider)
.subscribe { num ->
Log.i(TAG, "Started in onResume(), running until in onPause(): " + num)
}
Expand Down