Hi, does Jetpack Compose for Android have compose ...
# android
j
Hi, does Jetpack Compose for Android have compose "hooks"? IE I want to be notified of every (re)composition through my tree. Similar to Activity Lifecycle hooks.
j
I'm interested in knowing about this as well
๐Ÿ‘ 1
a
You can ask that in #compose
๐Ÿ‘ 1
a
what sorts of use cases do you have in mind?
j
@Adam Powell Third party SDKs that need to watch for tree changes to take action without having to have developers add code everywhere. Listening for a (re)composition would allow walking of the (sub)tree to see whats changed and act accordingly.
a
What kind of action?
j
If the context (text on screen, orientation, an image being shown, etc) meets some criteria do some IO
a
To what end?
j
Journey Management
Analytics/tracking with potential to optimize on the fly by asking for a recompose
a
Optimize what? Performance optimizations usually take the form of not recomposing rather than asking for more ๐Ÿ™‚
j
No, optimize content.
but the journey tracking is more important
a
Can you give an example?
I'm asking for more details because I suspect the answer to the initial question is going to be no, with no plans to add such a facility in the future. I'd like to explore some potential alternative approaches for what you're trying to do.
Global observers of the form it sounds like you're asking for would amount to a form of reflection, exposing a lot of implementation details of third-party components and expressing those private implementation details to you as if they were a stable public API.
If a library developer changed those details in a way that broke a particular inspection or manipulation you were performing, you'd probably have a bad time upgrading that library, or feel like contacting that developer and asking them to revert a change to something that they never intended to expose as a stable, unchanging API in the first place.
j
Business Users (ex. marketers) want to optimize content based on past actions of their App users journey without developer intervention. Example, a user has frequently visited the "support" context (text about reaching support, buttons to open chat, etc) and we want to know that (first use case, track) and then maybe on the 5th time provide some other content (button, text, something) so they can be better helped (second use case, optimize).
a
You would need to do that at a higher level of abstraction than the composition itself, e.g. observe the current location expressed by your navigation system and have the "support" context fed by a data source aware of any changes you made to app data about support based on those navigations.
j
That would require first party developer support. This is for a third party SDK that should just be integrated once and not require first party developers to do more than an initial configuration.
exposing a lot of implementation details of third-party components and expressing those private implementation details to you as if they were a stable public API.
We really only need to know when the tree changes and we will walk/reflect on it ourselves handling the internal api changes as necessary.
We already do this for the Android Platform components, legacy support library, and androidx (material by extension)
I really only need to know when the compose "primitives" (text, image loader, etc) emit changes (re)compose
Not other composables that compose those primitives
a
Compose doesn't make any distinction between those standard components or an arbitrary custom component that consumes space and draws pixels; there's not a type check you can use anywhere
j
Could this be done at the compiler lever to add a "metadata" element/tag (if you will)? IE compose compiler, annotation processor, aspectj, etc
So instead of listening/walking, during compilation each component will get an extra composable that will emit to the third party SDK therefore ignoring the events as it will just occur during (re)compose
a
maybe, but I imagine it would be extraordinarily brittle and subject to breakages on minor version updates of any other library involved as other things change
it sounds more or less like https://marketingplatform.google.com/about/tag-manager/ and we have no plans to support things like it as they go against the grain of single source of truth for data flow
j
okay, so forget optimizing content, what about just tracking?
a
if you're looking to track the visibility of elements you can write a
Modifier
that tracks the presence and position of an element on screen
j
I imagine it would be extraordinarily brittle and subject to breakages on minor version updates of any other library involved as other things change
What other libraries are you thinking of? I would only need to "weave" a composable into any App composable at compile time
if you're looking to track the visibility of elements you can write a Modifier that tracks the presence and position of an element on screen
requires first party developer support to integrate it into all of their composables. Not scaleable or easy to do after an app has been developed
a
not just first party developer support, but potentially third party as well depending on what the app itself integrates at what level of granularity
j
Exactly. So is compile time possible. IE
Copy code
@Composable
fun myChatComposable() {
  // during compile insert SDK composable here

  //...rest of myChatComposable
}
that way the SDK composable gets run automatically by (re)composition and it is in scope and contextual
a
I'm not sure there's a good/stable way to run such a thing at the right time during compilation (i.e. before or after compose performs its own transformations, or before or after inlining occurs) nor am I sure that you would get the results you're looking for by doing so. Recomposition is just one phase of constructing the UI; we skip it for different reasons at various layers of the call graph and restart further down the tree without re-running parents for different reasons. Some things, notably things like scrolling or positioning, happen at layout or drawing time and recomposition tends not to be involved at all.
Even if you did find a stable way to do this, the additional code you would need to insert at a great many levels to have the broad points of articulation you're looking for may have moderate to severe runtime performance penalties for the app.
It might be a fun science project to try it, but i'm not sure you would come out of the exercise with a shippable product in the end
j
how so? imagine it was hand written, the code would only be called when compose re-invokes the composable function.
๐Ÿ˜‚ Its part of our business today, can't be a science project for me unfortunately ๐Ÿ™‚ I need to find a solution
a
yes, but what would you want that code to then do? You get some code called when an app composable runs, then what?
j
based on context do IO. I can reflect objects in memory and send their data. The reflection would be minimized by only getting what a business user has configured.
little bit brittle based on app changes (if dev changes things, the business user needs to reconfig) but has potential
a
good luck ๐Ÿ™‚ I'm curious to see where your explorations lead. Definitely feel free to ask more questions over in #compose as things arise
๐Ÿ‘ 1
j
thanks for all your input!
๐Ÿ‘ 1