-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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 Android ViewObservable.input observe TextView instead of String #1545
Conversation
RxJava-pull-requests #1465 SUCCESS |
Aside from the public API change LGTM |
LGTM since 0.20 will have many breaking changes. |
Actually the only breaking API changes I'm aware of are in the Scala adaptor. There are some semantic changes that will affect some use cases, but all backpressure work is additive to APIs. If this change needs to be breaking, so be it, if everyone is okay with it. Can it be done via deprecation though so the old one is there also in 0.20 and then removed in 1.0? |
Definitely can bring back and deprecate the old version for 0.20. Honestly, |
+1 for text |
@@ -30,8 +30,8 @@ | |||
return Observable.create(new OperatorViewClick<T>(view, emitInitialValue)); | |||
} | |||
|
|||
public static Observable<String> input(final EditText input, final boolean emitInitialValue) { | |||
return Observable.create(new OperatorEditTextInput(input, emitInitialValue)); | |||
public static <T extends TextView> Observable<T> input(final T input, final boolean emitInitialValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would vote for having an overload that sets the 2nd argument to false. For simplicity.
…sion to ViewObservable.text
Just pushed a commit with the name change and bringing back the old, now deprecated, version. What are the philosophies for the repo on:
|
RxJava-pull-requests #1468 SUCCESS |
} | ||
}; | ||
|
||
final Subscription subscription = AndroidSubscriptions.unsubscribeInUiThread(new Action0() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjchristensen I could be mistaken, but is this still necessary? I believe OperatorObserveOn
schedules the unsubscribe action on the given scheduler already. So this might end up scheduling it twice? I guess it depends on whether we expect the caller to observeOn(mainThread())
explicitly?
Maybe this is part of a larger design question: who should be responsible for making sure that UI related code is executed on the UI thread? The operator? The client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends on where in the chain this operator is lifted. If after observeOn
then this code is needed, if before then I don't think it is needed.
There was a very lengthy discussion with @zsxwing at one point about this and it appeared there could be some extreme edge cases that could occur so I think this was done here to conservatively protect against that.
observeOn
does schedule the unsubscribe
: https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/internal/operators/OperatorObserveOn.java#L223 However, that is scheduling the unsubscribe
for this use case: https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/test/java/rx/internal/operators/OperatorObserveOnTest.java#L374 and it affects the "upstream", not "downstream" where I believe this operator will exist.
Thus, if OperatorTextView
is below the observeOn
operator and registering an unsubscribe
it is outside the control of observeOn
. That means it needs to schedule the behavior of input.removeTextChangedListener
in case the child Subscriber
is unsubscribed
on a thread other than the UI thread. If however this operator is above observeOn
then it should work fine as observeOn
would schedule the unsubscribe on the UI thread.
For example:
// observeOn has no control over the unsubscribe of TestViewInput here
someObservable.observeOn(AndroidScheduler).lift(OperatorTestViewInput).subscribe(unsubscribeAtSomePoint)
// but in this one it would
someObservable.lift(OperatorTestViewInput).observeOn(AndroidScheduler).subscribe(unsubscribeAtSomePoint)
@zsxwing am I correctly explaining the edge case that this is here for?
who should be responsible for making sure that UI related code is executed on the UI thread?
The observeOn
operator ensures the on*
events correctly get scheduled on the given Scheduler
, in this case the AndroidScheduler
.
Unsubscribes however are flowing the opposite direction, so any operators or Subscribers below observeOn
in the chain would need to handle their unsubscribe
scheduling themselves (or use unsubscribeOn
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjchristensen @zsxwing regarding "If however this operator is above observeOn then it should work fine as observeOn would schedule the unsubscribe on the UI thread."
I am not sure it is the case. Looking at https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/internal/operators/OperatorObserveOn.java#L223 it unsubscribes the worker but looking at https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/internal/operators/OperatorObserveOn.java#L101 the child unsubscribe() will chain upwards in the same thread instead?
I also am not sure I follow the reason why both https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/internal/operators/OperatorObserveOn.java#L89 and https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/internal/operators/OperatorObserveOn.java#L100 exist unsubscribing on 2 threads?
I generally prefer clarity if it's a small amount of code. When there is a lot (such as the Schedulers) then I reuse helper methods. |
Just pushed a commit to clarify the tests. Anything else that still needs to be addressed? |
LGTM |
RxJava-pull-requests #1489 ABORTED |
The aborted build is related to this: #1536 (comment) |
👍 |
Based on those votes I'll merge and include in next RC. |
Make Android ViewObservable.input observe TextView instead of String
The previous version required
ViewObservable.input(TextView, boolean)
to emit justString
s of the updated text, but notCharSequence
s, which is the declared implementation ofTextView
'smText
. This still allows for similar functionality as before via:It is also flexible like
ViewObservable.clicks
in that it returns a reference to theView
, which should make it more flexible for using it with other reactive methods.I held off from doing the same to
ViewObservable.input(CompoundButton, boolean)
but could do so if you think it would be valuable/more consistent.This would be a breaking change. In order to make it not a breaking change, this method could be renamed and the initial method could
map
like the above snippet. Let me know if you think this is important and I'd be happy to make this change.