-
Notifications
You must be signed in to change notification settings - Fork 637
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 support for rx.Single #39
Comments
Seems reasonable to me. BTW, you know that you misspelled "boycott", right? |
Also "GitHub" |
Note that it will be slightly more difficult because Single does not actually have a takeUntil operator so you will have to build that support yourself. Not sure how you will differentiate Observable vs. Single because you can't have a type implement both Observable.Transformer and Single.Transformer. You probably either have to have separate methods or your return value from bind methods is an object that has another method to get a Single version. The workaround for now is do toObservable before the compose call and toSingle after it. |
After pondering this for a while, it seems to me that instead of having two different versions - one for Justifications:
Any counterarguments? |
+1. If you're following RxJava 2.x dev discussions it was suggested just today that |
Migrating to 2.x means no longer doing Android as it'll be years if Android On Tue, Sep 29, 2015 at 6:26 PM Ben Sandee [email protected] wrote:
|
Regarding your points:
|
Update:
I believe it's not oversight as there is lack of more features (like retry). |
@phajduk If a |
@dlew You're right. I meant that there is no reason to implement Then 👍 from my side for using |
I just added
|
Awesome, we'll get those integrated once they're released. |
RxJava 1.1.2 is out and should work for both I have a branch open right now that does this, but wanted to get feedback on the API design. Specifically, we can't have overloads of A. Make overrides specifically named ( B. Make separate classes for Single and Completable with the same API. Open to suggestions. B seems like the cleaner approach, and much of the shared logic can be pulled out into package-local internals. |
I think it would be bad to change any of the existing method names. Another alternative (an A.5) would be to not change existing calls, but add versions of the methods with Single and Completable in the name. But I agree that B seems the best choice. |
A sort of moonshot option C: generic return type and have the method take a |
What'd be really nice is if I don't think we can get away with that with the current type system (though we could simplify our own implementation by having a single class that implements all three interfaces). I'll be thinking on this for a bit. I don't have any qualms with changing method signatures, TBH, we'll just deprecate/warn again. But it still seems like that route would create a method explosion. C seems like the most reasonable route to me so far, since we can guarantee our own type safety. |
I did try the custom transformer that implements all three, but unfortunately there are conflicting method signatures that it can't resolve :/ |
You'd have to cast in the |
After thinking on it for a while, I think I'd prefer option C. Mainly because there's a combinatorial explosion that'll happen each time we add a new method (if we duplicate methods for each type). I'm thinking that we'd still default to |
Been hacking at option C, but unfortunately I can' seem to get it to a state where it doesn't at least complain about casting in line. The following code: @NonNull
@CheckResult
public static <R> R bindActivity(
@NonNull final Class<? super R> transformerClass,
@NonNull final Observable<ActivityEvent> lifecycle) {
return bind(transformerClass, lifecycle, ACTIVITY_LIFECYCLE);
}
@SuppressWarnings("unchecked")
@NonNull
@CheckResult
public static <T, R> R bind(
@NonNull final Class<?> transformerClass,
@NonNull final Observable<T> lifecycle,
@Nullable final Func1<T, T> correspondingEvents) {
checkNotNull(transformerClass, "transformerClass == null");
checkNotNull(lifecycle, "lifecycle == null");
// Make sure we're truly comparing a single stream to itself
final Observable<T> sharedLifecycle = lifecycle.share();
final Observable<?> eventMappingObservable = correspondingEvents == null
? lifecycle
: eventMappingObservable(sharedLifecycle, correspondingEvents);
// Keep emitting from source until the corresponding event occurs in the lifecycle
if (Completable.CompletableTransformer.class.isAssignableFrom(transformerClass)) {
return (R) new Completable.CompletableTransformer() {
@Override
public Completable call(Completable completable) {
return completable.ambWith(eventMappingObservable.toCompletable());
}
};
} else if (Observable.Transformer.class.isAssignableFrom(transformerClass)) {
return (R) new Observable.Transformer<T, T>() {
@Override
public Observable<T> call(Observable<T> source) {
return source.takeUntil(eventMappingObservable);
}
};
} else if (Observable.Transformer.class.isAssignableFrom(transformerClass)) {
return (R) new Single.Transformer<T, T>() {
@Override
public Single<T> call(Single<T> source) {
return source.takeUntil(eventMappingObservable);
}
};
} else {
throw new IllegalArgumentException("Unsupported target class");
}
} Results in this: |
This seems to work for me: public static <T, R> T bind(Observable<R> lifecycle, Class<T> transformerType) {
// Implement here
} |
Ah, yeah, I do get that. That's because you can't define the generic type of the returned I played around with it a bit and got a little further, but haven't quite solved it yet. You can do this: public static <T extends Func1<R, R>, R> T basicTransformer() {
// Do whatever here
} Then you can do this: Observable.Transformer<String, String> transformer = basicTransformer(); And it doesn't complain. But if you try to use |
There has always been issues with the generic type inference with RxLifecycle and the compose method. See issues #44, #58, and #59. As it stands today in Kotlin I have to explicitly add a type parameter. Would be great if the type inference can be fixed once and for all, but the problem may actually be with RxJava's declaration of compose as well. |
Yeah unfortunately mixing doesn't really work either since |
Any updates on this? Seems to have stalled a month ago. In the process of converting som Observables to Single and Completable |
It's stalled out due to soul searching. The way the API is would need to be setup means that supporting I feel like this is going to be a problem for any library built on top of RxJava, so I'm a bit frustrated with how the design shook out. As a result, what I've been considering is simply not supporting |
I can say with lots of calls, the whole toObservable() toX() pairing is a I wonder if this might be a solution. Right now all the bind calls return
Where you implement the methods to convert for single and completable. Then for users, they just have to do something like:
|
That's an interesting solution! It looks like a decent mixture of common case/back-compat support but also being able to support the other types. I think I'll explore that sometime this week. |
Seems that parts of your API were missed. ActivitiyLifecycleProvider does not have the change to support Single and Completable and also Navi component does not have it. |
D'oh. Will fix. |
FYI have submitted PR for RxJava2 that will allow a single object to act as transformer for all reactive types: ReactiveX/RxJava#4672 |
Excellent, thanks! |
And the PR was just merged, so RxLifeCycle for RxJava2 won't need this workaround. |
Single is the alternate version of Observable and should be supported to automatically unsubscribe based on Lifecycle events as well.
The text was updated successfully, but these errors were encountered: