1576883: Concurrent recomposition API | <https://a...
# compose
s
1576883: Concurrent recomposition API | https://android-review.googlesource.com/c/platform/frameworks/support/+/1576883 Status:
Merged
. Does this tell us we will have multithreaded composition soon? โ˜บ๏ธ
a
But memoisation (remember, etc.) is a side effect by definition, isn't it? It remembers into some sort of a scoped state.
My concern mostly about cases when you have to use libraries that require access only from main thread. E.g. there might be main thread checks in constructors, so you won't be able to create and remember such objects in composition.
j
Remember looks like a side effect, but it is an API internal to Compose, which means that mathematically it can be treated as a return value that Compose. That (along with the invocations of all other composable functions) could conceptually be rewritten by the compiler as a return value that tells Compose what should happen, very similar to the way Flutter and React return elements from their build/render functions respectively. We don't do that in practice for performance reasons, but that's an implementation detail, and we're able to manage the consistency guarantees around those APIs because they are mathematically equivalent. But this is a very subtle/nuanced difference, and it was one of my biggest misgivings about the remember API, because it's hard for most users to understand the difference. The real concern is about any side-effect that impacts data that Compose doesn't control. With regards to libraries that require access to the main thread - yeah, don't use those. If you're using those directly from a composable function, your composable function probably isn't a pure functional transform from data to UI, so you're really not following the rules anyway. All of this should become much better described once we actually have it all working and we can get DevRel to help with figuring out how to make the messaging more understandable, but in the mean time, anything you can do to reduce side-effects and thread-constraints will be a good thing and your future self will thank you.
๐Ÿ‘ 1
s
what libraries can have main thread checks in constructors? I mean other than custom views I can't remember any.
a
MVICore, MVIKotlin. Plus due to multiplatform , you may want use shared ViewModel. And due to Kotlin Native memory model you will likely require main thread only access. Of course you can lift restrictions for non-native, but I believe it is better to keep the behaviour consistent across platforms.
s
you can update your libraries ๐Ÿ˜›
a
I don't want to update as of now. I think it is common use case to remember ViewModels inside Composable functions. And they may and will often have side effects in constructors. My opinion is that design decision is super error prone and will lead to same situation as with Kotlin Native memory model. When you often shooting you legs and it is very hard to debug.
Maybe guarantee main thread for first composition would solve the issue.
s
So devs who will use such libswill simply disable multi-threaded composition :) multi-threaded composition was announced at very beginning. And it is super important feature.
๐Ÿ‘ 2
a
Maybe there could be a solution to satisfy both cases?
s
What JB says? I heard they planned to rework KN memory model.
j
Yeah, JB's new memory model will open things up a lot, and you probably don't want to use ViewModels anyway because they aren't MPP, but these are all things that will become more clear once we have working prototypes.
๐Ÿ‘ 9
a
They will rework the memory model but it will require a lot of time. Also people are using ViewModels in MPP already quite a lot. Because ViewModels are nothing more than just an interface with single
onCleared
method. There is
moko-mvvm
and others. Looking forward for multi-threaded composition, but also hope there will be a way to
remember
on main thread.
a
If you need to interface with main thread-only libraries, doing so from the
*Effect
APIs will continue to meet those expectations. We currently have no plans for a main thread-restricted
remember
, you'll need to
remember
a wrapper object that performs any main thread initialization either via
DisposableEffect
or by implementing
RememberObserver
.
โค๏ธ 1
Using
by mutableStateOf
to back your ViewModel object properties also gives them a baseline of thread safety for composition, as composition always occurs in a snapshot that won't be modified by another thread during that composition.
โค๏ธ 1
c
I'm super new to compose, and jumping in a little late here, but just wanted to add that something feels really wrong by using AAC VMs inside of a composable. So far I've only built like 10 composables, but I always try to pass the data it needs into the composable from the viewModel and try not to give the composable a VM directly.
๐Ÿ‘† 2
๐Ÿ’ฏ 3
a
generally yes, but parameters passed have to come from somewhere. If that's some coarse-grained subcomponent of a screen that might be implemented as a fragment pre-compose, it's not necessarily strange to use an AAC VM for its object retention facilities in a composable function playing the same role as that kind of fragment, passing data from the VM down to the other composables it invokes as parameters.
๐Ÿ‘ 1
I'd generally caution against writing AAC VMs with main thread requirements or side effects of construction with or without compose
๐Ÿ’ฏ 2
๐Ÿ‘ 1
๐Ÿ‘† 2