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 additional extension methods for android-archcomponents #348

Merged
merged 10 commits into from
May 14, 2019
5 changes: 1 addition & 4 deletions android/autodispose-android-archcomponents/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ dependencies {

androidTestImplementation project(':android:autodispose-android-archcomponents-test')
androidTestImplementation project(':test-utils')
androidTestImplementation(deps.test.androidExtJunit) {
// https://issuetracker.google.com/issues/117486311
exclude group: "org.junit"
}
androidTestImplementation deps.test.androidExtJunit
androidTestImplementation deps.test.androidRunner
androidTestImplementation deps.test.androidRules
androidTestUtil deps.test.androidOrchestrator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,22 @@ package com.uber.autodispose.android.lifecycle
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Lifecycle.Event
import androidx.lifecycle.LifecycleOwner
import com.uber.autodispose.AutoDispose
import com.uber.autodispose.FlowableSubscribeProxy
import com.uber.autodispose.ObservableSubscribeProxy
import com.uber.autodispose.SingleSubscribeProxy
import com.uber.autodispose.MaybeSubscribeProxy
import com.uber.autodispose.CompletableSubscribeProxy
import com.uber.autodispose.ParallelFlowableSubscribeProxy
import com.uber.autodispose.ScopeProvider
import com.uber.autodispose.lifecycle.CorrespondingEventsFunction
import io.reactivex.annotations.CheckReturnValue
import io.reactivex.parallel.ParallelFlowable
import io.reactivex.Observable
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.Single
import io.reactivex.Completable

/**
* Extension that returns a [ScopeProvider] for this [LifecycleOwner].
Expand Down Expand Up @@ -77,3 +90,99 @@ inline fun Lifecycle.scope(
boundaryResolver: CorrespondingEventsFunction<Event>
): ScopeProvider = AndroidLifecycleScopeProvider.from(
this, boundaryResolver)

/**
* Extension that proxies to [Flowable.as] + [AutoDispose.autoDisposable] and takes an [untilEvent] when
* subscription will be disposed.
ShaishavGandhi marked this conversation as resolved.
Show resolved Hide resolved
*
* @param lifecycleOwner The lifecycle owner.
* @param untilEvent Optional lifecycle event when subscription will be disposed.
*/
@CheckReturnValue
inline fun <T> Flowable<T>.autoDisposable(lifecycleOwner: LifecycleOwner, untilEvent: Event? = null): FlowableSubscribeProxy<T> {
return if (untilEvent == null) {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
} else {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, untilEvent)))
}
}

/**
* Extension that proxies to [Observable.as] + [AutoDispose.autoDisposable] and takes an [untilEvent] when
* subscription will be disposed.
*
* @param lifecycleOwner The lifecycle owner.
* @param untilEvent Optional lifecycle event when subscription will be disposed.
*/
@CheckReturnValue
inline fun <T> Observable<T>.autoDisposable(lifecycleOwner: LifecycleOwner, untilEvent: Event? = null): ObservableSubscribeProxy<T> {
return if (untilEvent == null) {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
} else {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, untilEvent)))
}
}

/**
* Extension that proxies to [Single.as] + [AutoDispose.autoDisposable] and takes an [untilEvent] when
* subscription will be disposed.
*
* @param lifecycleOwner The lifecycle owner.
* @param untilEvent Optional lifecycle event when subscription will be disposed.
*/
@CheckReturnValue
inline fun <T> Single<T>.autoDisposable(lifecycleOwner: LifecycleOwner, untilEvent: Event? = null): SingleSubscribeProxy<T> {
return if (untilEvent == null) {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
} else {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, untilEvent)))
}
}

/**
* Extension that proxies to [Maybe.as] + [AutoDispose.autoDisposable] and takes an [untilEvent] when
* subscription will be disposed.
*
* @param lifecycleOwner The lifecycle owner.
* @param untilEvent Optional lifecycle event when subscription will be disposed.
*/
@CheckReturnValue
inline fun <T> Maybe<T>.autoDisposable(lifecycleOwner: LifecycleOwner, untilEvent: Event? = null): MaybeSubscribeProxy<T> {
return if (untilEvent == null) {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
} else {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, untilEvent)))
}
}

/**
* Extension that proxies to [Completable.as] + [AutoDispose.autoDisposable] and takes an [untilEvent] when
* subscription will be disposed.
*
* @param lifecycleOwner The lifecycle owner.
* @param untilEvent Optional lifecycle event when subscription will be disposed.
*/
@CheckReturnValue
inline fun Completable.autoDisposable(lifecycleOwner: LifecycleOwner, untilEvent: Event? = null): CompletableSubscribeProxy {
return if (untilEvent == null) {
this.`as`(AutoDispose.autoDisposable<Any>(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
} else {
this.`as`(AutoDispose.autoDisposable<Any>(AndroidLifecycleScopeProvider.from(lifecycleOwner, untilEvent)))
}
}

/**
* Extension that proxies to [ParallelFlowable.as] + [AutoDispose.autoDisposable] and takes an [untilEvent] when
* subscription will be disposed.
*
* @param lifecycleOwner The lifecycle owner.
* @param untilEvent Optional lifecycle event when subscription will be disposed.
*/
@CheckReturnValue
inline fun <T> ParallelFlowable<T>.autoDisposable(lifecycleOwner: LifecycleOwner, untilEvent: Event? = null): ParallelFlowableSubscribeProxy<T> {
return if (untilEvent == null) {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
} else {
this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, untilEvent)))
}
}
5 changes: 1 addition & 4 deletions android/autodispose-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ dependencies {
testImplementation deps.test.truth
androidTestImplementation project(':test-utils')
androidTestImplementation deps.androidx.annotations
androidTestImplementation(deps.test.androidExtJunit) {
// https://issuetracker.google.com/issues/117486311
exclude group: "org.junit"
}
androidTestImplementation deps.test.androidExtJunit
androidTestImplementation deps.test.androidRunner
androidTestImplementation deps.test.androidRules
androidTestUtil deps.test.androidOrchestrator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,78 @@
package com.uber.autodispose.android

import android.view.View
import com.uber.autodispose.AutoDispose
import com.uber.autodispose.FlowableSubscribeProxy
import com.uber.autodispose.ObservableSubscribeProxy
import com.uber.autodispose.SingleSubscribeProxy
import com.uber.autodispose.MaybeSubscribeProxy
import com.uber.autodispose.CompletableSubscribeProxy
import com.uber.autodispose.ParallelFlowableSubscribeProxy
import com.uber.autodispose.ScopeProvider
import io.reactivex.Flowable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.Maybe
import io.reactivex.Completable
import io.reactivex.annotations.CheckReturnValue
import io.reactivex.parallel.ParallelFlowable

/**
* Extension that returns a [ScopeProvider] for this [View].
*/
@CheckReturnValue
inline fun View.scope(): ScopeProvider = ViewScopeProvider.from(this)

/**
* Extension that proxies to [Flowable.as] + [AutoDispose.autoDisposable]
*/
@CheckReturnValue
inline fun <T> Flowable<T>.autoDisposable(
view: View
): FlowableSubscribeProxy<T> =
this.`as`(AutoDispose.autoDisposable(ViewScopeProvider.from(view)))

/**
* Extension that proxies to [Observable.as] + [AutoDispose.autoDisposable]
*/
@CheckReturnValue
inline fun <T> Observable<T>.autoDisposable(
view: View
): ObservableSubscribeProxy<T> =
this.`as`(AutoDispose.autoDisposable(ViewScopeProvider.from(view)))

/**
* Extension that proxies to [Single.as] + [AutoDispose.autoDisposable]
*/
@CheckReturnValue
inline fun <T> Single<T>.autoDisposable(
view: View
): SingleSubscribeProxy<T> =
this.`as`(AutoDispose.autoDisposable(ViewScopeProvider.from(view)))

/**
* Extension that proxies to [Maybe.as] + [AutoDispose.autoDisposable]
*/
@CheckReturnValue
inline fun <T> Maybe<T>.autoDisposable(
view: View
): MaybeSubscribeProxy<T> =
this.`as`(AutoDispose.autoDisposable(ViewScopeProvider.from(view)))

/**
* Extension that proxies to [Completable.as] + [AutoDispose.autoDisposable]
*/
@CheckReturnValue
inline fun Completable.autoDisposable(
view: View
): CompletableSubscribeProxy =
this.`as`(AutoDispose.autoDisposable<Any>(ViewScopeProvider.from(view)))

/**
* Extension that proxies to [ParallelFlowable.as] + [AutoDispose.autoDisposable]
*/
@CheckReturnValue
inline fun <T> ParallelFlowable<T>.autoDisposable(
view: View
): ParallelFlowableSubscribeProxy<T> =
this.`as`(AutoDispose.autoDisposable(ViewScopeProvider.from(view)))
12 changes: 12 additions & 0 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ android {
defaultConfig {
minSdkVersion deps.build.minSdkVersion
targetSdkVersion deps.build.targetSdkVersion

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testApplicationId "com.uber.autodispose.android.lifecycle.androidTest"
}
compileOptions {
sourceCompatibility deps.build.javaVersion
Expand All @@ -51,6 +54,9 @@ android {
matchingFallbacks = ['release']
}
}
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}

// def classesWithScope = [
// "android.app.Activity",
Expand Down Expand Up @@ -100,4 +106,10 @@ dependencies {
def leakcanaryVersion = '1.6.2'
debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakcanaryVersion"
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanaryVersion"

androidTestImplementation project(':test-utils')
androidTestImplementation deps.test.androidRunner
androidTestImplementation deps.test.androidRules
androidTestUtil deps.test.androidOrchestrator
androidTestImplementation deps.test.androidExtJunit
}
107 changes: 107 additions & 0 deletions sample/src/androidTest/java/com/uber/autodispose/TestKotlinActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (C) 2019. Uber Technologies
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.uber.autodispose

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import com.uber.autodispose.android.autoDisposable
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider
import com.uber.autodispose.android.lifecycle.autoDisposable
import com.uber.autodispose.android.lifecycle.scope
import io.reactivex.Maybe
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.Completable
import io.reactivex.CompletableSource
import io.reactivex.Flowable
import org.junit.Ignore
import java.util.concurrent.TimeUnit

/**
* Test Activity class to verify compilation of various extension functions.
*/
@Ignore("Since it's only used to verify compilation of the extension functions")
class TestKotlinActivity : AppCompatActivity(), ScopeProvider {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just to doubly confirm - it doesn't get confused about ambiguous types here if targeting this now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, it doesn't. Basically, it will always just resolve to one of those extension functions. It will ask you for one of them. If you're overloading with the untilEvent, it will always resolve to the one with LifecycleOwner.


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

// With extension function that overloads LifecycleOwner
Observable.interval(1, TimeUnit.SECONDS)
.autoDisposable(this)
.subscribe()

// With extension function that overloads LifecycleOwner and until Event
Observable.interval(1, TimeUnit.SECONDS)
.autoDisposable(this, Lifecycle.Event.ON_DESTROY)
.subscribe()

// With extension function that overloads ScopeProvider
Observable.interval(1, TimeUnit.SECONDS)
.autoDisposable(scope(Lifecycle.Event.ON_DESTROY))
.subscribe()

// With no extension function
Observable.interval(1, TimeUnit.SECONDS)
.autoDisposable(AndroidLifecycleScopeProvider.from(this))
.subscribe()

Maybe.just(1)
.autoDisposable(this)
.subscribe()

Maybe.just(1)
.autoDisposable(this, Lifecycle.Event.ON_DESTROY)
.subscribe()

Flowable.just(1)
.autoDisposable(this)
.subscribe()

Flowable.just(1)
.autoDisposable(this, Lifecycle.Event.ON_DESTROY)
.subscribe()

Single.just(1)
.autoDisposable(this)
.subscribe()

Single.just(1)
.autoDisposable(this, Lifecycle.Event.ON_DESTROY)
.subscribe()

Completable.never()
.autoDisposable(this)
.subscribe()

Completable.never()
.autoDisposable(this, Lifecycle.Event.ON_DESTROY)
.subscribe()

val rootView = findViewById<View>(android.R.id.content)

// Taking scope of a View
Observable.interval(1, TimeUnit.DAYS)
.autoDisposable(rootView)
.subscribe()
}

override fun requestScope(): CompletableSource {
return Completable.complete()
}
}