How do you expose activity/view lifecycles to squa...
# squarelibraries
v
How do you expose activity/view lifecycles to square/workflow? I was thinking of passing it in as a prop, or did I miss some out of the box way of doing this? (Couldn't find an example in the samples) @Zach Klippenstein (he/him) [MOD] @Ray Ryan
r
We’ve talked about doing the prop thing too, it makes a lot of sense. Although the the word “it” is carrying a lot of weight in that question.
What are you actually trying to do? The hope was that
WorkflowRunner
is already as tied into the lifecycle as you should need to be.
z
Activity/view lifecycle events are just UI events, and can be delivered to a workflow that cares about them in as rendering events like usual.
v
Need to query gps status onResume and kick-off/update a workflow with a location stream if gps is permitted.
r
That sounds like the gps status should be a prop
WorkflowRunner
should allow you to update the props, looking for a snippet.
v
Found it on
WorkflowFragment
r
Or are you saying want a workflow to do the gps query, and to be notified onResume?
v
Copy code
* A fragment to run a workflow whose configuration may need to be updated could
* provide a method like this:
*
*   class HelloWorkflowFragment : WorkflowFragment<HelloInput, Unit>() {
*     private val inputs = BehaviorSubject.createDefault(HelloInput.Fnord)
*
*     fun input(input: HelloInput) = inputs.onNext(input)
*
*     override fun onCreateWorkflow(): Config<HelloInput, Unit> {
*       return Config(
*           workflow = HelloWorkflow,
*           inputs = inputs
*       )
*     }
*   }
*/
r
Yeah, and you can do the same in activity
Important thing to understand is that Props aren’t events, they’re more state like.
👍 1
As I type this, realizing that we could totally put the current
androidx.lifecycle.Lifecycle.State
in the props. 🙂
1
v
I think I'll pass in the lifecyle (resumed/started/etc) into the parent workflow and just read it to kick off a gps worker which can update state in the parent workflow which the parent can use to start the right child
👍 1
r
I like that.
v
thanks people
z
That sounds like the right approach: pull state and interaction with the external world up, push down to children in props.
🙂 1
v
Something i've noticed, whenever we introduce a workflow as a part of some flow in our app, we end up doing something messy to implement clean up logic since layout runners don't get notified (AFAIK) when workflows terminate, and workflow termination is handled in non-workflow land.
r
Why should layout runners care about that?
If they’re doing work that needs to be cleaned up, seems worrisome.
Esp. if onDetachedFromWindow isn’t notification enough
v
One example in our app is that we already have a google map object before a workflow kicks off. We start a workflow that may add some markers to this map. When this workflow terminates, we need to clear markers if any were placed.
r
I’d give the workflow a cleanup state in that case, and add a
val cleanup:  Boolean
to the rendering
(frickin’ Slack rich text editor)
Possibly also add an event the view can send when the cleanup is done, if the timing is important.
🤔 1
@Zach Klippenstein (he/him) [MOD] maybe another use case for Controlled Components? 🙂
z
I don’t understand the setup. Who owns the map object? Is it in the view layer or the workflow layer? Are any other parts of your app mutating state on this map object?
v
The map object is owned by a controller that attaches the workflow and populates the
ContainerHints
so the layour runner can reference the map. Nothing else in the app mutates the map while the workflow is attached.
If all logic in our app that decides what to draw on the map moves to a workflow, then this wouldn't be a problem. Until then though I guess event flags in the renderings is the way to go.
z
The set of markers to place on the map is view model data. The workflow should communicate that set in its rendering. Then the controller that owns the map view can set the actual markers on the map as appropriate, including removing them all when the workflow stops running.
whenever we introduce a workflow as a part of some flow in our app, we end up doing something messy to implement clean up logic since layout runners don’t get notified (AFAIK) when workflows terminate
`LayoutRunner`s can handle cleanup by listening to when their view is detached. We probably need to document this explicitly. `Workflow`s can handle cleanup by using a
LifecycleWorker
and implementing
onStopped
. If a
LayoutRunner
needs to differentiate between its being detached due to something like config change, and due to the backing workflow going away, that’s a smell that one of them is trying to do too much. In fact, `LayoutRunner`s aren’t tied to workflows directly at all – theoretically, a container runner could decide to start or stop running a child runner independently from changes in the workflow tree (e.g. using
ContainerHints
).
👍 1
workflow termination is handled in non-workflow land
Not sure what you mean exactly. You mean that non-workflow code needs to be aware of when a workflow terminates? There are two ways to handle this:
Worker
being run by the workflow is cancelled, or the workflow’s rendering stops being emitted. Although either of these things can occur for reasons other than the workflow actually stopping. The actual workflow lifecycle is not exposed by design.