You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@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:
The work is paused (current, but deprecated behavior of whenStarted)
Let the suspending code continue to run to completion (even if state falls below target state)
Cancel the suspending code and restart it when you come back above that state.
Cancel the suspending code and don't restart it
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:
viewModel.onEach(State::property) { property ->
binding.textView.text = "A" // guaranteed state above Started
delay(1000)
binding.textView.text = "B" // no guarantee
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
Behavior 3 & 4 do not make much sense as on higher level there is a DeliveryMode (UniqueOnly, RedeliverOnStart) which allow to configure similar behavior - RedeliveryOnStart=Behavior 3, UniqueOnly=Behavior 4
Behavior 1 (current, with whenStarted) only makes sense with UniqueOnly, as with RedeliverOnStart previous work will not be resumed (so it will be equivalent to Behavior 4). It will be cancelled because of new 'redeliver' emission
override fun onCreate(savedInstanceState: Bundle?) {
viewModel.onEach(ViewState::isVisible) { isVisible ->
...
binding.someview.reveal() // (1) suspendable, performs animation
binding.someview.text = "" // (2) touches other UI after continuation
...
}
}
Despite 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, so binding.someview.text = "" will never be called
Issue 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 correct
@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.onEachbehaved 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
whenStartedAs 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 withRedeliverOnStartprevious 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
UniqueOnlydelivery 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.onEachthat 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 correct