Marko Novakovic
01/27/2021, 5:57 PMReading a state that was created after the snapshot was taken or in a snapshot that has not yet been applied
cb
01/27/2021, 6:19 PMMarko Novakovic
01/27/2021, 6:21 PMJetNews
for practise. This happens when I click on Home
drawer item when Home
is already selectedMarko Novakovic
01/27/2021, 6:21 PME/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: com.marko.myjetnews, PID: 6766
java.lang.IllegalStateException: Reading a state that was created after the snapshot was taken or in a snapshot that has not yet been applied
at androidx.compose.runtime.snapshots.SnapshotKt.readError(Snapshot.kt:1521)
at androidx.compose.runtime.snapshots.SnapshotKt.current(Snapshot.kt:1697)
at androidx.compose.runtime.SnapshotMutableState.setValue(MutableState.kt:326)
at com.marko.myjetnews.home.HomeViewModel.setPosts(HomeViewModel.kt:39)
at com.marko.myjetnews.home.HomeViewModel.access$setPosts(Unknown Source:0)
at com.marko.myjetnews.home.HomeViewModel$1.invokeSuspend(HomeViewModel.kt:33)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Marko Novakovic
01/27/2021, 6:22 PMvar posts by savedStateHandle.mutableStateOf<List<Post>>(
key = SAVED_POSTS,
initialState = emptyList(),
save = { bundleOf(SAVED_POSTS to it) },
restore = { it.getParcelableArrayList<Post>(SAVED_POSTS) ?: emptyList() },
)
private set
Marko Novakovic
01/27/2021, 6:23 PMfun <T> SavedStateHandle.mutableStateOf(
key: String,
initialState: T,
save: (T) -> Bundle,
restore: (Bundle) -> T,
): MutableState<T> {
val bundle: Bundle? = get(key)
val initial = if (bundle == null) initialState else restore(bundle)
val state = mutableStateOf(initial)
setSavedStateProvider(key) { save(state.value) }
return state
}
Chuck Jazdzewski [G]
01/27/2021, 9:10 PMmutableStateOf
was read before snapshot it was created in was applied. This is most-likely caused by creating a muttableStateOf
in composition and capturing it in a lambda invoked outside composition (such as in a coroutine).
My guess, from the stacks, is a coroutine that (probably indirectly) captured the posts
field of HomeViewModel
was started before the composition that create the view model was applied. Consider using LaunchEffect
to start the coroutine instead as it waits until the composition applies successfully to start the coroutine avoiding such issues. Alternately, you can create the view model outside composition and pass it in as a parameter. All mutableStateOf
created outside a snapshot (such as taken during composition) are automatically applied before any other snapshot is taken.Marko Novakovic
01/27/2021, 10:38 PM