Hi all! I can’t figure out how to change state and...
# compose
n
Hi all! I can’t figure out how to change state and cause a recomposition from outside (not onClick or anything). E.g. from a timer. This:
Copy code
val counter = state { 0 }
timer(period = 16L) { counter.value++ }
Gives me an exception:
Copy code
Exception in thread "Timer-0" java.lang.IllegalStateException: Not in a frame
	at androidx.compose.frames.FramesKt.currentFrame(Frames.kt:180)
	at androidx.compose.frames.FramesKt.writable(Frames.kt:461)
	at androidx.compose.ModelMutableState.setValue(MutableState.kt:176)
m
Afaik you can only update the state on the main thread. I guess this will change in the future.
n
But onClicks work somehow? Those are not happening on main thread?
m
Im pretty sure onClick will be called on the main thread.
☝️ 2
n
is there a way to schedule work there?
s
https://stackoverflow.com/questions/11123621/running-code-in-main-thread-from-another-thread You can get the Context from the ContextAmbient.current (on dev 5)
l
right now you need to be in a “frame” to mutate an @Model instance. The main thread is special in that it always has a frame open. You can open and commit a frame in a background thread if you want (think of it like a “transaction” that you commit or abort etc). Or, you can just execute the mutation on the main thread (for instance, by scheduling something on a Handler with the main looper).
we have plans to change the way this system works a little bit to introduce a “global transaction” which means that mutating them will always be valid no matter where you are, but you will lose some of the snapshot isolation if you are not in a frame. this seems to produce a happier path for users in the sense that you will never get an exception like the above, but you can still take advantage of the snapshot isolation when you need to
👍🏻 2