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
Added reactive versions of Activities and Fragments #93
Conversation
I really don't like the naming here. I would prefix these with "Rx" or something to disambiguate. |
Should this be part of the rxandroid-framework module?
|
@dlew I see the rational behind the subclassing of those. As you mentioned it can save some boilerplate code, however I don't think this is the way to go. If we go down that road it is quite restrictive for users and we have to maintain Multiple copies of those (what about FragmentActivity, or other subclasses ?). |
I'm fine with renaming the classes if people think that's best; I was just following the pattern of the support lib, which doesn't rename. I find that makes it easier to switch between versions since it's just a package name swap. I'm also fine with this going into rxandroid-framework, which I didn't know existed (probably because it just appeared a couple days ago, hah). |
I've come up with a metric for any given solution to RxAndroid problems, which is "is it better than doing it yourself?" For example: in the case of the lifecycle, "doing it yourself" would be manually handling a Measured by this yardstick, there's basically no way of doing better than
Subclassing seems to be the only solution to reducing boilerplate. Any other solution is going to be just as laborious as |
This is straight-up what we use at Trello and it is extremely convenient. Given that, I definitely think it should be called |
@dlew 👍 I don't see any simple way either. Let's get this into framework then. |
Framework module already has |
eb3ef5e
to
38e85aa
Compare
Modified and rebased. Here's what I did:
|
@dlew We should probably rename the ReactiveDialog to something else. |
|
||
@Override | ||
protected void onPause() { | ||
super.onPause(); |
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.
Shouldn't the super.onXX() be the last call?
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.
Why?
@dlew might need rebase |
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
lifecycleSubject.onNext(LifecycleEvent.CREATE); |
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.
don't you want to pass savedInstanceState with the create event?
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.
Maybe eventually? The goal here isn't to get rid of having to override onCreate()
, but giving a way to detect when onCreate()
has been called so other reactive code can... react.
I'm open to explore this more later but I'd rather start minimalist then add as necessary.
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.
@dlew totally makes sense
38e85aa
to
0122aa9
Compare
super.onStart(); | ||
|
||
subscription = | ||
LifecycleObservable.bindActivityLifecycle(lifecycle(), ViewObservable.clicks(button)) |
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.
Do you think click listener observable is a good example here?
Have you experienced a necessity to bind such an observable to the lifecycle in practice?
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.
If no one ever had use for binding a click listener in practice, why do we bother having ViewObservable.clicks()
?
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'm not speaking about necessity of click observable. But whether it is
necessary to unsubscribe in this case. Unsubscription in this case leads to
remove of click listener. And I personally rarely need to do it in onStop
or in onDestroy.
On 14:57, Sat, Nov 29, 2014 Daniel Lew notifications@github.com wrote:
In
sample-app/src/main/java/rx/android/samples/LifecycleObservableActivity.java:
- @OverRide
- protected void onCreate(Bundle savedInstanceState) {
super.onCreate(
savedInstanceState);
button = new Button(this);
button.setText("Click Me!");
setContentView(button);
- }
- @OverRide
- protected void onStart() {
super.onStart();
subscription =
LifecycleObservable.bindActivityLifecycle(lifecycle(), ViewObservable.clicks(button))
If no one ever had use for binding a click listener in practice, why do we
bother having ViewObservable.clicks()?—
Reply to this email directly or view it on GitHub
https://github.com/ReactiveX/RxAndroid/pull/93/files#r21053708.
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.
Try removing the unsubscribe. The activity will leak. At least it did last
time I tested the sample.
On Sat, Nov 29, 2014, 10:26 Roman Mazur notifications@github.com wrote:
In
sample-app/src/main/java/rx/android/samples/LifecycleObservableActivity.java:
- @OverRide
- protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button = new Button(this);
button.setText("Click Me!");
setContentView(button);
- }
- @OverRide
- protected void onStart() {
super.onStart();
subscription =
LifecycleObservable.bindActivityLifecycle(lifecycle(), ViewObservable.clicks(button))
I'm not speaking about necessity of click observable. But whether it is
necessary to unsubscribe in this case. Unsubscription in this case leads to
remove of click listener. And I personally rarely need to do it in onStop
or in onDestroy.
… <#msg-f:1486120348025889653_>
On 14:57, Sat, Nov 29, 2014 Daniel Lew notifications@github.com wrote:
In
sample-app/src/main/java/rx/android/samples/LifecycleObservableActivity.java:
- @OverRide https://github.com/Override > + protected void
onCreate(Bundle savedInstanceState) { > + super.onCreate(
savedInstanceState); > + > + button = new Button(this); > +
button.setText("Click Me!"); > + setContentView(button); > + } > + > +
@OverRide https://github.com/Override > + protected void onStart() { >- super.onStart(); > + > + subscription = > +
LifecycleObservable.bindActivityLifecycle(lifecycle(),
ViewObservable.clicks(button)) If no one ever had use for binding a click
listener in practice, why do we bother having ViewObservable.clicks()? —
Reply to this email directly or view it on GitHub <
https://github.com/ReactiveX/RxAndroid/pull/93/files#r21053708>.—
Reply to this email directly or view it on GitHub
https://github.com/ReactiveX/RxAndroid/pull/93/files#r21054500.
I read quickly through the PR and I do not see any major objections to this. Maybe we can merge this after some 👍 ? |
I think @dpsm 's remarks need addressing (re. order of method invocation for onPause/onStop/onDestroy etc) We should inform the subscriber before the fragment view gets destroyed about the fact that it's about to get destroyed. |
@mttkay I've been torn on that one. People extending I'm looking for a strong argument one way or the other; even though you expect it to fire before an event, my intuitive understanding is that it fires after the event. I'm not sure which is clearer. |
I would understand these hooks as a chance for the subscriber to perform any clean up prior to the fragment getting destroyed. If that logic depends on the state prior to destruction (after destruction there is no state to rely on after all), then this might break the subscriber because, for instance, |
@mttkay 👍 |
Yes, that's exactly what I would vote for. By the way, Android has a Linter check for exactly that. If you override an Activity/Fragment/Service, and you dispatch e.g. super.onDestroy before your own calls when overriding these hooks, it'll fail the check. |
Actually it might have been PMD not Android lint. |
Includes both built-in versions + support versions. Minus any sort of weird annotation hacking, this seems to be the "best" method for creating a version of the base UI component classes that we can hook into.
0122aa9
to
c5504c0
Compare
SGTM. Fixed ordering and rebased. |
Added reactive versions of Activities and Fragments
Subclasses of the common
Activity
andFragment
classes, extended so you can easily get anObservable<LifecycleEvent>
.I wanted to get the ball rolling on this discussion (since it's the second part of #12, as I viewed it). I am fully aware this may be a controversial move. :P
I tried working up a version using
ActivityLifecycleCallbacks
, but it felt too weird to have one solution forActivity
and another forFragment
. Also, watching #84 has caused me to realize there are multiple places where being able to hook into theActivity
orFragment
directly will save a lot of boilerplate.I purposefully chose to not rename the subclasses. That way, when you extend, say,
Activity
the package resolution dialog will show this version as well.One conspicuously missing extension is
ActionBarActivity
, since it depends on #83.