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

Add untilEvent overload for AndroidLifecycleScopeProvider#from #107

Merged
merged 4 commits into from
Oct 10, 2017
Merged
Show file tree
Hide file tree
Changes from 3 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 @@ -24,11 +24,11 @@
import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.LifecycleEndedException;
import com.uber.autodispose.test.RecordingObserver;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.PublishSubject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.PublishSubject;

import static com.google.common.truth.Truth.assertThat;

Expand Down Expand Up @@ -165,6 +165,73 @@
lifecycle.emit(Lifecycle.Event.ON_DESTROY);
}

@Test @UiThreadTest public void observable_createPause() {
final RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
final PublishSubject<Integer> subject = PublishSubject.create();

// Spin it up
TestAndroidLifecycleScopeProvider lifecycle = new TestAndroidLifecycleScopeProvider();
lifecycle.emit(Lifecycle.Event.ON_CREATE);
subject.to(AutoDispose.with(AndroidLifecycleScopeProvider
.from(lifecycle, Lifecycle.Event.ON_PAUSE))
.<Integer>forObservable())
.subscribe(o);
lifecycle.emit(Lifecycle.Event.ON_START);
lifecycle.emit(Lifecycle.Event.ON_RESUME);

Disposable d = o.takeSubscribe();
o.assertNoMoreEvents(); // No initial value.

subject.onNext(0);
assertThat(o.takeNext()).isEqualTo(0);

subject.onNext(1);
assertThat(o.takeNext()).isEqualTo(1);

// We should stop here
lifecycle.emit(Lifecycle.Event.ON_PAUSE);
subject.onNext(2);
o.assertNoMoreEvents();

lifecycle.emit(Lifecycle.Event.ON_STOP);
lifecycle.emit(Lifecycle.Event.ON_DESTROY);
}

@Test @UiThreadTest public void observable_resumeDestroy() {
final RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
final PublishSubject<Integer> subject = PublishSubject.create();

// Spin it up
TestAndroidLifecycleScopeProvider lifecycle = new TestAndroidLifecycleScopeProvider();
lifecycle.emit(Lifecycle.Event.ON_CREATE);
lifecycle.emit(Lifecycle.Event.ON_START);
lifecycle.emit(Lifecycle.Event.ON_RESUME);
subject.to(AutoDispose.with(AndroidLifecycleScopeProvider
.from(lifecycle, Lifecycle.Event.ON_DESTROY))
.<Integer>forObservable())
.subscribe(o);

Disposable d = o.takeSubscribe();
o.assertNoMoreEvents(); // No initial value.

subject.onNext(0);
assertThat(o.takeNext()).isEqualTo(0);

subject.onNext(1);
assertThat(o.takeNext()).isEqualTo(1);

lifecycle.emit(Lifecycle.Event.ON_PAUSE);
lifecycle.emit(Lifecycle.Event.ON_STOP);

subject.onNext(2);
assertThat(o.takeNext()).isEqualTo(2);

// We should stop here
lifecycle.emit(Lifecycle.Event.ON_DESTROY);
subject.onNext(3);
o.assertNoMoreEvents();
}

@Test public void observable_offMainThread_shouldFail() {
RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
PublishSubject<Integer> subject = PublishSubject.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
public final class AndroidLifecycleScopeProvider
implements LifecycleScopeProvider<Lifecycle.Event> {

private static final Function<Lifecycle.Event, Lifecycle.Event> CORRESPONDING_EVENTS =
private static final Function<Lifecycle.Event, Lifecycle.Event> DEFAULT_CORRESPONDING_EVENTS =
new Function<Lifecycle.Event, Lifecycle.Event>() {
@Override public Lifecycle.Event apply(Lifecycle.Event lastEvent) throws Exception {
switch (lastEvent) {
Expand All @@ -54,41 +54,85 @@ public final class AndroidLifecycleScopeProvider
}
};

private final Function<Lifecycle.Event, Lifecycle.Event> correspondingEvents;

/**
* Creates a {@link AndroidLifecycleScopeProvider} for Android LifecycleOwners.
*
* @param owner the owner to scope for
* @param owner the owner to scope for.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor: Missing dot.

* @return a {@link AndroidLifecycleScopeProvider} against this owner.
*/
public static AndroidLifecycleScopeProvider from(LifecycleOwner owner) {
return from(owner.getLifecycle());
}

/**
* Creates a {@link AndroidLifecycleScopeProvider} for Android LifecycleOwners.
*
* @param owner the owner to scope for.
* @param untilEvent the event until the scope is valid.
* @return a {@link AndroidLifecycleScopeProvider} against this owner.
*/
public static AndroidLifecycleScopeProvider from(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more nit - if they start on a new line, let's make each of them a separate line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like this?

public static AndroidLifecycleScopeProvider from(
          LifecycleOwner owner, 
          Lifecycle.Event untilEvent) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

LifecycleOwner owner, Lifecycle.Event untilEvent) {
return from(owner.getLifecycle(), untilEvent);
}

/**
* Creates a {@link AndroidLifecycleScopeProvider} for Android Lifecycles.
*
* @param lifecycle the lifecycle to scope for
* @param lifecycle the lifecycle to scope for.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

* @return a {@link AndroidLifecycleScopeProvider} against this lifecycle.
*/
public static AndroidLifecycleScopeProvider from(Lifecycle lifecycle) {
return new AndroidLifecycleScopeProvider(lifecycle);
}

/**
* Creates a {@link AndroidLifecycleScopeProvider} for Android Lifecycles.
*
* @param lifecycle the lifecycle to scope for.
* @param untilEvent the event until the scope is valid.
* @return a {@link AndroidLifecycleScopeProvider} against this lifecycle.
*/
public static AndroidLifecycleScopeProvider from(
Lifecycle lifecycle, Lifecycle.Event untilEvent) {
return new AndroidLifecycleScopeProvider(lifecycle, untilEvent);
}

private final LifecycleEventsObservable lifecycleObservable;

private AndroidLifecycleScopeProvider(Lifecycle lifecycle) {
this.lifecycleObservable = new LifecycleEventsObservable(lifecycle);
this.correspondingEvents = DEFAULT_CORRESPONDING_EVENTS;
}

private AndroidLifecycleScopeProvider(Lifecycle lifecycle, Lifecycle.Event untilEvent) {
this.lifecycleObservable = new LifecycleEventsObservable(lifecycle);
this.correspondingEvents = new UntilEventFunction(untilEvent);
}

@Override public Observable<Lifecycle.Event> lifecycle() {
return lifecycleObservable;
}

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

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

private static class UntilEventFunction implements Function<Lifecycle.Event, Lifecycle.Event> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I'd initially thought about doing it as a filter, but with this you hook in nicely to the api

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I started trying that but could not get it to work, so came up with this approach instead.

private final Lifecycle.Event untilEvent;

UntilEventFunction(Lifecycle.Event untilEvent) {
this.untilEvent = untilEvent;
}

@Override public Lifecycle.Event apply(Lifecycle.Event event) throws Exception {
return untilEvent;
}
}
}
21 changes: 19 additions & 2 deletions sample/src/main/java/com/uber/autodispose/sample/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@

package com.uber.autodispose.sample;

import android.arch.lifecycle.Lifecycle;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import java.util.concurrent.TimeUnit;

/**
* Demo activity, shamelessly borrowed from the RxLifecycle sample
Expand All @@ -35,7 +37,7 @@ public class MainActivity extends AppCompatActivity {

private static final String TAG = "AutoDispose";

@Override protected void onCreate(Bundle savedInstanceState) {
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added @Nullable annotation as suggested by Android Studio.

super.onCreate(savedInstanceState);

Log.d(TAG, "onCreate()");
Expand Down Expand Up @@ -95,6 +97,21 @@ public class MainActivity extends AppCompatActivity {
// `.<Long>forObservable` is necessary if you're compiling on JDK7 or below.
// If you're using JDK8+, then you can safely remove it.
.to(AutoDispose.with(AndroidLifecycleScopeProvider.from(this)).<Long>forObservable())
.subscribe(new Consumer<Long>() {
@Override public void accept(Long num) throws Exception {
Log.i(TAG, "Started in onResume(), running until in onPause(): " + num);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed "...running until in onDestroy" to "...running until in onPause".

}
});

// Setting a specific untilEvent, this should dispose in onDestroy.
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose(new Action() {
@Override public void run() throws Exception {
Log.i(TAG, "Disposing subscription from onResume() with untilEvent ON_DESTROY");
}
})
.to(AutoDispose.with(AndroidLifecycleScopeProvider.from(this,
Lifecycle.Event.ON_DESTROY)).<Long>forObservable())
.subscribe(new Consumer<Long>() {
@Override public void accept(Long num) throws Exception {
Log.i(TAG, "Started in onResume(), running until in onDestroy(): " + num);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.uber.autodispose.sample

import android.arch.lifecycle.Lifecycle
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
Expand Down Expand Up @@ -70,6 +71,16 @@ class KotlinActivity : AppCompatActivity() {
.subscribe { num ->
Log.i(TAG, "Started in onResume(), running until in onPause(): " + num)
}

// Setting a specific untilEvent, this should dispose in onDestroy.
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose {
Log.i(TAG, "Disposing subscription from onResume() with untilEvent ON_DESTROY")
}
.autoDisposeWith(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY))
.subscribe{ num ->
Log.i(TAG, "Started in onResume(), running until in onDestroy(): " + num)
}
}

override fun onPause() {
Expand Down