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

Arch components lifecycle support #71

Merged
merged 21 commits into from
Sep 10, 2017
Merged

Arch components lifecycle support #71

merged 21 commits into from
Sep 10, 2017

Conversation

ZacSweers
Copy link
Collaborator

@ZacSweers ZacSweers commented May 24, 2017

This is a first pass of support for Android Architecture Components' Lifecycle support. This works fairly similarly to ViewScopeProvider from a structural standpoint. LifecycleOwner or Lifecycle can be passed in, an inner observer is passed in and removed upon disposal.

Thoughts for discussion:

  • Name is up for grabs. This one's a bit long :)
  • Should it be its own artifact? I'm leaning toward this, then we could also do an alpha release of it separately.
  • Things get a bit convoluted for me around State vs. Event. I'm not sure which one we should watch for, but all the querying APIs revolve around State so I went with that.
  • Does it matter if it's on the main thread?

If this looks good - I'll take a pass at tests.

I think this would also resolve #36 and #37 by just supporting them (in the support lib anyway)


@OnLifecycleEvent(Lifecycle.Event.ON_ANY) void onStateChange() {
if (!isDisposed()) {
observer.onNext(lifecycle.getCurrentState());
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure if this could result in duplicate state emissions since this fires on events. Will find out

@@ -49,6 +49,7 @@ dependencies {
compile deps.rx.java
compile deps.rx.android
compile deps.support.annotations
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for a separate module approach

Copy link

Choose a reason for hiding this comment

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

+1. at least until we call it beta (which means stable api)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yup moved it

Copy link

Choose a reason for hiding this comment

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

btw, you don't need extensions, you should only need lifecycle:common

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

cool, I'll remove it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually I remember now why I added it, I need LifecycleRegistry for the TestAndroidLifecycleScopeProvider implementation. Added back in 1c06bef

switch (lastEvent) {
case INITIALIZED:
throw new LifecycleNotStartedException();
case CREATED:
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the lifecycle intentionally not 1-1? It seems very strange to have multiple start events map to the same stop event.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There's only one stop event, not sure why

Copy link

Choose a reason for hiding this comment

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

I think you are confusing states vs events.
https://developer.android.com/topic/libraries/architecture/lifecycle.html

e.g. both onStart and onPause brings you to the STARTED state. I'm not sure where you are using these but this seems wrong.

@jaychang0917
Copy link

I think Event is more suitable since you can't manage to cancel subscription in corresponding lifecycle event (e.g. onResume -> onPause) if you use State.

@ZacSweers
Copy link
Collaborator Author

Yep event is the right way to go. Sorry for the lag on this, kind of mentally put it on the backburner since it was still in alpha. Will jump on it this coming week

@ZacSweers
Copy link
Collaborator Author

So I'm a little stuck on this right now. I've switched the implementation to events, but I'm not sure how to test this. I tried writing this as an espresso test (similar to how the -android artifact is), but lifecycle events when manipulating activities in espresso seem to fire events in random order.

@yigit
Copy link

yigit commented Aug 29, 2017

fyi, you don't need to keep this as a separate artifact, Lifecycle's core libs will be a dependency of support Fragments so all apps will have them.

@ZacSweers
Copy link
Collaborator Author

yeah I was just making it separate for while it was in alpha, but maybe you'll beat me to it :)

@ZacSweers
Copy link
Collaborator Author

ZacSweers commented Aug 30, 2017

Will handle rebasing before merging later. Going to figure out testing for this now

@ZacSweers
Copy link
Collaborator Author

Ok, things should be ready to go here. Going to do a rebase

@ZacSweers
Copy link
Collaborator Author

Rebased. Requesting review from @tonycosentini and @jbarr21, also welcome feedback from anyone else on the thread :)

subject.onNext(2);
o.assertNoMoreEvents();

d.dispose();
Copy link
Contributor

Choose a reason for hiding this comment

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

Dumb question - why is this needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don’t remember (this test is largely a copy of the viewscopeprovidertest), I think it’s not and I just did it out of habit or something. Will try removing

Copy link
Collaborator Author

Choose a reason for hiding this comment

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


@SuppressWarnings("CheckReturnValue") LifecycleEventsObservable(Lifecycle lifecycle) {
this.lifecycle = lifecycle;
// Backfill if already created for boundary checking
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: doesn't seem like it matters with today's implementation - but would it ever be beneficial to replay all the previous events?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure what you mean. Like having that be a use case of the library?

@Override protected void subscribeActual(Observer<? super Event> observer) {
if (!isMainThread()) {
observer.onError(
new IllegalStateException("Lifecycles can only be bound to on the main thread!"));
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a strict requirement with the new architecture library?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not necessarily but it's always emitted on the main thread and you could have a race condition if you don't.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Checked with @yigit, answer is yes otherwise no guarantees

This is a first pass of support for Android Architecture Components' `Lifecycle` support. This works fairly similarly to `ViewScopeProvider` from a structural standpoint. `LifecycleOwner` or `Lifecycle` can be passed in, an inner observer is passed in and removed upon disposal.

Thoughts for discussion:
  - Name is up for grabs. This one's a bit long :)
  - Should it be its own artifact? I'm leaning toward this, then we could also do an alpha release of it separately.
  - Things get a bit convoluted for me around `State` vs. `Event`. I'm not sure which one we should watch for, but all the querying APIs revolve around `State` so I went with that.
  - Does it matter if it's on the main thread?

If this looks good - I'll take a pass at tests.
WIP still as I don't really know how to test this nicely
DESTROY is _before_ INITIALIZED apparently
@ZacSweers
Copy link
Collaborator Author

Rebased and ran UI tests locally

@ZacSweers ZacSweers merged commit ca3139f into master Sep 10, 2017
@ZacSweers ZacSweers deleted the z/archLifecycle branch September 10, 2017 22:45
@ZacSweers ZacSweers modified the milestone: 0.3.0 Sep 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add demo scope provider for Activity
4 participants