diff --git a/rx/src/main/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandler.java b/rx/src/main/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandler.java index 5dd4b6ce..7549b1f1 100644 --- a/rx/src/main/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandler.java +++ b/rx/src/main/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandler.java @@ -37,7 +37,7 @@ public void onChange(final TiPresenter.State state, final boolean hasLifecycleMethodBeenCalled) { if (state == TiPresenter.State.VIEW_DETACHED && !hasLifecycleMethodBeenCalled) { // unsubscribe all UI subscriptions created in onAttachView() and added - // via manageViewSubscription(Subscription) + // via manageViewSubscriptions(Subscription) if (mUiSubscriptions != null) { mUiSubscriptions.unsubscribe(); mUiSubscriptions = null; @@ -57,34 +57,65 @@ public void onChange(final TiPresenter.State state, } /** - * Add your subscriptions here and they will automatically unsubscribed when + * Add your subscription here and they will automatically unsubscribed when * {@link TiPresenter#destroy()} gets called * * @throws IllegalStateException when the presenter has reached {@link net.grandcentrix.thirtyinch.TiPresenter.State#DESTROYED} + * @see #manageSubscriptions(Subscription...) */ - public void manageSubscription(@NonNull final Subscription... subscriptions) { + public Subscription manageSubscription(@NonNull final Subscription subscription) { if (mPresenterSubscriptions == null) { throw new IllegalStateException("subscription handling doesn't work" + " when the presenter has reached the DESTROYED state"); } - mPresenterSubscriptions.addAll(subscriptions); + mPresenterSubscriptions.add(subscription); + return subscription; } /** - * Add your subscriptions for View events to this method to get them automatically cleaned up - * in {@link TiPresenter#detachView()}. typically call this in {@link - * TiPresenter#attachView(TiView)} where you subscribe to the UI events. + * Add your subscriptions here and they will automatically unsubscribed when + * {@link TiPresenter#destroy()} gets called + * + * @throws IllegalStateException when the presenter has reached {@link net.grandcentrix.thirtyinch.TiPresenter.State#DESTROYED} + * @see #manageSubscription(Subscription) + */ + public void manageSubscriptions(@NonNull final Subscription... subscriptions) { + for (int i = 0; i < subscriptions.length; i++) { + manageViewSubscription(subscriptions[i]); + } + } + + /** + * Add your subscription for View events to this method to get them automatically cleaned up + * in {@link TiPresenter#detachView()}. Typically call this in + * {@link TiPresenter#attachView(TiView)} where you subscribe to the UI events. * * @throws IllegalStateException when no view is attached + * @see #manageViewSubscriptions(Subscription...) */ - public void manageViewSubscription(@NonNull final Subscription... subscriptions) { + public Subscription manageViewSubscription(@NonNull final Subscription subscription) { if (mUiSubscriptions == null) { - throw new IllegalStateException("view subscriptions can't be handled" + throw new IllegalStateException("view subscription can't be handled" + " when there is no view"); } - mUiSubscriptions.addAll(subscriptions); + mUiSubscriptions.add(subscription); + return subscription; + } + + /** + * Add your subscriptions for View events to this method to get them automatically cleaned up + * in {@link TiPresenter#detachView()}. Typically call this in + * {@link TiPresenter#attachView(TiView)} where you subscribe to the UI events. + * + * @throws IllegalStateException when no view is attached + * @see #manageViewSubscription(Subscription) + */ + public void manageViewSubscriptions(@NonNull final Subscription... subscriptions) { + for (int i = 0; i < subscriptions.length; i++) { + manageViewSubscription(subscriptions[i]); + } } } diff --git a/rx/src/test/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandlerTest.java b/rx/src/test/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandlerTest.java index 30b943ad..48505985 100644 --- a/rx/src/test/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandlerTest.java +++ b/rx/src/test/java/net/grandcentrix/thirtyinch/rx/RxTiPresenterSubscriptionHandlerTest.java @@ -23,9 +23,11 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import rx.Subscription; import rx.observers.TestSubscriber; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.fail; @@ -68,6 +70,17 @@ public void testManageSubscription_AfterDestroy_ShouldThrowIllegalState() throws } } + @Test + public void testManageSubscription_ShouldReturnSameSubscription() throws Exception { + mPresenter.create(); + mPresenter.attachView(mView); + final TestSubscriber testSubscriber = new TestSubscriber<>(); + + final Subscription subscription = mSubscriptionHandler.manageSubscription(testSubscriber); + + assertThat(testSubscriber, is(equalTo(subscription))); + } + @Test public void testManageSubscription_WithAlreadyUnsubscribedSubscription_ShouldDoNothing() throws Exception { @@ -91,6 +104,18 @@ public void testManageSubscription_WithDestroy_ShouldUnsubscribe() throws Except testSubscriber.assertUnsubscribed(); } + @Test + public void testManageViewSubscription_ShouldReturnSameSubscription() throws Exception { + mPresenter.create(); + mPresenter.attachView(mView); + final TestSubscriber testSubscriber = new TestSubscriber<>(); + + final Subscription subscription = + mSubscriptionHandler.manageViewSubscription(testSubscriber); + + assertThat(testSubscriber, is(equalTo(subscription))); + } + @Test public void testManageViewSubscription_WithDetachSingleSub_ShouldUnsubscribe() throws Exception { @@ -118,9 +143,12 @@ public void testManageViewSubscription_WithDetachView_ShouldUnsubscribe() throws } @Test - public void testManageViewSubscription_manageBeforeViewAttached_ShouldThrowIllegalStateException() + public void testManageViewSubscription_manageAfterDetach_ShouldThrowIllegalStateException() throws Exception { mPresenter.create(); + mPresenter.attachView(mView); + mPresenter.detachView(); + TestSubscriber testSubscriber = new TestSubscriber<>(); try { @@ -132,12 +160,9 @@ public void testManageViewSubscription_manageBeforeViewAttached_ShouldThrowIlleg } @Test - public void testManageViewSubscription_manageAfterDetach_ShouldThrowIllegalStateException() + public void testManageViewSubscription_manageBeforeViewAttached_ShouldThrowIllegalStateException() throws Exception { mPresenter.create(); - mPresenter.attachView(mView); - mPresenter.detachView(); - TestSubscriber testSubscriber = new TestSubscriber<>(); try { @@ -157,7 +182,7 @@ public void testManageViewSubscriptions_WithOneAlreadyUnsubscribed_ShouldNotAddT TestSubscriber secondSubscriber = new TestSubscriber<>(); secondSubscriber.unsubscribe(); - mSubscriptionHandler.manageViewSubscription(firstSubscriber, secondSubscriber); + mSubscriptionHandler.manageViewSubscriptions(firstSubscriber, secondSubscriber); assertThat(firstSubscriber.isUnsubscribed(), equalTo(false)); secondSubscriber.assertUnsubscribed(); @@ -172,7 +197,7 @@ public void testManagerViewSubscriptions_WithDetach_ShouldUnsubcribe() throws Ex TestSubscriber thirdSubscriber = new TestSubscriber<>(); mSubscriptionHandler - .manageViewSubscription(firstSubscriber, secondSubscriber, thirdSubscriber); + .manageViewSubscriptions(firstSubscriber, secondSubscriber, thirdSubscriber); assertThat(firstSubscriber.isUnsubscribed(), equalTo(false)); assertThat(secondSubscriber.isUnsubscribed(), equalTo(false)); assertThat(thirdSubscriber.isUnsubscribed(), equalTo(false)); diff --git a/rx2/src/main/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandler.java b/rx2/src/main/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandler.java index 10192f48..09a17964 100644 --- a/rx2/src/main/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandler.java +++ b/rx2/src/main/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandler.java @@ -58,34 +58,63 @@ public void onChange(final TiPresenter.State state, } /** - * Add your disposables here and they will automatically disposed when + * Add your disposable here and they will automatically disposed when * {@link TiPresenter#destroy()} gets called * * @throws IllegalStateException when the presenter has reached {@link net.grandcentrix.thirtyinch.TiPresenter.State#DESTROYED} */ - public void manageDisposable(@NonNull final Disposable... disposables) { + public Disposable manageDisposable(@NonNull final Disposable disposable) { if (mPresenterDisposables == null) { throw new IllegalStateException("disposable handling doesn't work" + " when the presenter has reached the DESTROYED state"); } - mPresenterDisposables.addAll(disposables); + mPresenterDisposables.add(disposable); + return disposable; } + /** - * Add your disposables for View events to this method to get them automatically cleaned up - * in {@link TiPresenter#detachView()}. typically call this in {@link - * TiPresenter#attachView(TiView)} where you dispose to the UI events. + * Add your disposables here and they will automatically disposed when + * {@link TiPresenter#destroy()} gets called + * + * @throws IllegalStateException when the presenter has reached {@link net.grandcentrix.thirtyinch.TiPresenter.State#DESTROYED} + * @see #manageDisposable(Disposable) + */ + public void manageDisposables(@NonNull final Disposable... disposable) { + for (int i = 0; i < disposable.length; i++) { + manageDisposable(disposable[i]); + } + } + + /** + * Add your disposable for View events to this method to get them automatically cleaned up + * in {@link TiPresenter#detachView()}. typically call this in + * {@link TiPresenter#attachView(TiView)} where you dispose to the UI events. * * @throws IllegalStateException when no view is attached */ - public void manageViewDisposable(@NonNull final Disposable... disposables) { + public Disposable manageViewDisposable(@NonNull final Disposable disposable) { if (mUiDisposables == null) { throw new IllegalStateException("view disposable can't be handled" + " when there is no view"); } - mUiDisposables.addAll(disposables); + mUiDisposables.add(disposable); + return disposable; + } + + /** + * Add your disposables for View events to this method to get them automatically cleaned up + * in {@link TiPresenter#detachView()}. typically call this in + * {@link TiPresenter#attachView(TiView)} where you dispose to the UI events. + * + * @throws IllegalStateException when no view is attached + */ + public void manageViewDisposables(@NonNull final Disposable... disposables) { + for (int i = 0; i < disposables.length; i++) { + manageViewDisposable(disposables[i]); + } } } diff --git a/rx2/src/test/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandlerTest.java b/rx2/src/test/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandlerTest.java index 6a6be215..64688ae2 100644 --- a/rx2/src/test/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandlerTest.java +++ b/rx2/src/test/java/net/grandcentrix/thirtyinch/rx2/RxTiPresenterDisposableHandlerTest.java @@ -23,6 +23,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import io.reactivex.disposables.Disposable; import io.reactivex.observers.TestObserver; import static org.hamcrest.CoreMatchers.containsString; @@ -37,13 +38,13 @@ public class RxTiPresenterDisposableHandlerTest { private RxTiPresenterDisposableHandler mDisposableHandler; - private TiPresenter mPresenter; + private TiPresenter mPresenter; private TiView mView; @Before public void setUp() throws Exception { - mPresenter = new TiPresenter() { + mPresenter = new TiPresenter() { }; mDisposableHandler = new RxTiPresenterDisposableHandler(mPresenter); mView = mock(TiView.class); @@ -63,6 +64,17 @@ public void testManageDisposable_AfterDestroy_ShouldThrowIllegalState() throws E } } + @Test + public void testManageDisposable_ShouldReturnSameDisposable() throws Exception { + mPresenter.create(); + mPresenter.attachView(mView); + final TestObserver testObserver = new TestObserver<>(); + + final Disposable disposable = mDisposableHandler.manageDisposable(testObserver); + + assertThat(testObserver, is(equalTo(disposable))); + } + @Test public void testManageDisposable_WithAlreadyDisposedDisposable_ShouldDoNothing() throws Exception { @@ -101,6 +113,17 @@ public void testManageVieDisposable_WithDetachSingleDispose_ShouldDispose() assertThat(testObserver.isDisposed(), is(true)); } + @Test + public void testManageViewDisposable_ShouldReturnSameDisposable() throws Exception { + mPresenter.create(); + mPresenter.attachView(mView); + final TestObserver testObserver = new TestObserver<>(); + + final Disposable disposable = mDisposableHandler.manageViewDisposable(testObserver); + + assertThat(testObserver, is(equalTo(disposable))); + } + @Test public void testManageViewDisposable_manageAfterDetach_ShouldThrowIllegalStateException() throws Exception { @@ -141,7 +164,7 @@ public void testManageViewDisposeable_WithOneAlreadyDisposed_ShouldNotAddToDispo final TestObserver secondTestObserver = new TestObserver<>(); secondTestObserver.dispose(); - mDisposableHandler.manageViewDisposable(firstTestObserver, secondTestObserver); + mDisposableHandler.manageViewDisposables(firstTestObserver, secondTestObserver); assertThat(firstTestObserver.isDisposed(), is(false)); assertThat(secondTestObserver.isDisposed(), is(true)); @@ -156,7 +179,7 @@ public void testManagerViewDisposable_WithDetach_ShouldDispose() throws Exceptio final TestObserver thirdTestObserver = new TestObserver<>(); mDisposableHandler - .manageViewDisposable(firstTestObserver, secondTestObserver, thirdTestObserver); + .manageViewDisposables(firstTestObserver, secondTestObserver, thirdTestObserver); assertThat(firstTestObserver.isDisposed(), equalTo(false)); assertThat(secondTestObserver.isDisposed(), equalTo(false)); assertThat(thirdTestObserver.isDisposed(), equalTo(false)); diff --git a/sample/src/main/java/net/grandcentrix/thirtyinch/sample/HelloWorldPresenter.java b/sample/src/main/java/net/grandcentrix/thirtyinch/sample/HelloWorldPresenter.java index cb528596..0c65afe4 100644 --- a/sample/src/main/java/net/grandcentrix/thirtyinch/sample/HelloWorldPresenter.java +++ b/sample/src/main/java/net/grandcentrix/thirtyinch/sample/HelloWorldPresenter.java @@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit; import rx.Observable; +import rx.Subscription; import rx.functions.Func1; import rx.schedulers.Schedulers; import rx.subjects.BehaviorSubject; @@ -44,13 +45,13 @@ public class HelloWorldPresenter extends TiPresenter { protected void onAttachView(@NonNull final HelloWorldView view) { super.onAttachView(view); - rxSubscriptionHelper.manageViewSubscription(mText.asObservable() - .subscribe(view::showText)); - - rxSubscriptionHelper.manageViewSubscription(view.onButtonClicked() + final Subscription showTextSub = mText.asObservable().subscribe(view::showText); + final Subscription onButtonClickSub = view.onButtonClicked() .subscribe(aVoid -> { triggerHeavyCalculation.onNext(null); - })); + }); + + rxSubscriptionHelper.manageViewSubscriptions(showTextSub, onButtonClickSub); } @Override