-
Notifications
You must be signed in to change notification settings - Fork 500
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
Discuss whenStarted function deprecation #705
Comments
By |
@sav007 yes, it is already work this way today (link)
|
So the plan here is to revert wrapper that we put other day I believed we already discuss this but maybe we can back to the drawing board again and think is there any other way to make it clear for user to not use |
Yes
I think new API or lint check might be too intrusive as after the update you have to update hundreds of usages (or you will end up with multiple APIs like Since selectSubscribe/onEach were designed to be called only after
|
Thanks for your detailed thoughts, as always, @denis-bezrukov! IIRC, I don't think With whatever we decide, the main use cases that I think about are:
I also don't love that onEach's behavior implicitly changes depending on the availability of @denis-bezrukov your third option of always resolving to viewLifecycleOwner sounds interesting. While potentially complex, if we can take on the complexity in the library to make it easier and safer for everybody else, that seems worth it. Are there cases you can think of where always using viewLifecycleOwner would break currently working behavior? |
Thanks for the detailed write up. At Airbnb we have always used the onViewCreated callback for any onEach registrations, and it has worked well for us. I believe if there are any cases where somebody wants that callback to continue working even when the view is destroyed, then the behavior must be by definition unrelated to the view and therefore should be able to be done in the viewmodel instead anyway. The one exception I can think of is if the callback needs to access other viewmodels, especially since it isn't always easy or possible to access one viewmodel from another. That should be a very rare case, but it is possibly something we still need to support. I like the idea of using the view lifecycle owner livedata to guarantee that we only subscribe to the view lifecycle. It would be cleaner than trying to ensure via docs and lint that everyone does the right thing. However, it's not immediately clear to me how we would achieve that. I think we would also need to offer an escape hatch to customize the lifecycle scope if needed |
From a brief look at how we might make that change, we might change It does look like handling all of the details correctly could be complex though to ensure the behavior is correct in all cases |
@gpeal @elihart @sav007
In Lifecycle 2.6.0 the functions whenXXX/launchWhenXXX were deprecated, see explanation here
Overall they outline four options for the work to behave when the lifecycle fall below "X" state:
whenStarted
)Initially, maverick's
viewModel.onEach
behaved as 2 - the callback was guaranteed to be triggered when lifecycle state is above state, but execution wasn't paused/cancelled if the state falls below started state.e.g. the following was possible:
In #665 the behavior was changed to 1, as the callback is wrapped into
whenStarted
As it is deprecated now (in #689 deprecations were suppressed), eventually it might be removed/hidden so we need to figure out what would be the best expected behavior for mavericks.
Here are my thoughts
DeliveryMode
(UniqueOnly
,RedeliverOnStart
) which allow to configure similar behavior -RedeliveryOnStart
=Behavior 3,UniqueOnly
=Behavior 4whenStarted
) only makes sense withUniqueOnly
, as withRedeliverOnStart
previous work will not be resumed (so it will be equivalent to Behavior 4). It will be cancelled because of new 'redeliver' emissionwhenStarted
#665Despite it fixes crash (if view's lifecycle fall into DESTROYED state, while fragment's lifecycle is still in CREATED), it introduce some potential issues.
Issue 1 - the code won't be ever "resumed" from suspended state just because of
RedeliverOnStart
, sobinding.someview.text = ""
will never be calledIssue 2 - even if it would resume (e.g. if
UniqueOnly
delivery mode was used),binding.someview.text = ""
might reference to another view (if view was recreated).I think the proper solution/advice would be to move
viewModel.onEach
that does "suspending stuff with a view" to Fragment.onViewCreated. In this case the job will be created in view's lifecycle scope, so the animation will be tied to view rather than fragment which is more correctThe text was updated successfully, but these errors were encountered: