koin
koin copied to clipboard
java.lang.IllegalStateException: Compose Runtime internal error after updating to Koin 3.2.0
Description After updating to Koin 3.2.0 from 3.1.6 my Compose app crashes with
java.lang.IllegalStateException: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (Start/end imbalance).
Tried with 3.1.5 and 3.1.6 both work fine. Updating to 3.2.0 causes this crash. I believe this is a bug in Koin.
Also came across a similar issue on Google's issue tracker: https://issuetracker.google.com/issues/233126425 The author also appears to be using Koin.
Expected behavior App should not crash
Version
koin-core version 3.2.0
koin-android version 3.2.0
koin-androidx-compose version 3.2.0
+1 same here, needed to downgrade to 3.1.6 to get it working again.
any solutions?
any more stack trace or way to reproduce?
politely bumping this issue.
Stacktrace:
Java.lang.IllegalStateException: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (Start/end imbalance). Please report to Google or use https://goo.gle/compose-feedback
at androidx.compose.runtime.ComposerKt.composeRuntimeError(Composer.kt:3466)
at androidx.compose.runtime.ComposerImpl.finalizeCompose(Composer.kt:3550)
at androidx.compose.runtime.ComposerImpl.endRoot(Composer.kt:1237)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2588)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2547)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:620)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:786)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:105)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:456)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:425)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:997)
at android.view.Choreographer.doCallbacks(Choreographer.java:797)
at android.view.Choreographer.doFrame(Choreographer.java:728)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:984)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@de5e03, StandaloneCoroutine{Cancelling}@8a52180, AndroidUiDispatcher@78473b9]
I also got the crash but noticed if I move the line out of the setContent
method the error seems to have vanished:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Moved the following line to here...
val homePageViewModel: HomePageViewModel by viewModel()
setContent {
// ...Because here it caused the crash (commented out)
// val homePageViewModel: HomePageViewModel by viewModel()
val navController = rememberNavController()
MaterialTheme {
Surface(
modifier = Modifier.fillMaxSize(),
) {
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomePage(navController, homePageViewModel) }
composable("search") { SearchPage() }
/*...*/
}
}
}
}
}
}
Not sure why the error occurs if I inject the viewModel
within the setContent
function
I also got the crash but noticed if I move the line out of the
setContent
method the error seems to have vanished:class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Moved the following line to here... val homePageViewModel: HomePageViewModel by viewModel() setContent { // ...Because here it caused the crash (commented out) // val homePageViewModel: HomePageViewModel by viewModel() val navController = rememberNavController() MaterialTheme { Surface( modifier = Modifier.fillMaxSize(), ) { NavHost(navController = navController, startDestination = "home") { composable("home") { HomePage(navController, homePageViewModel) } composable("search") { SearchPage() } /*...*/ } } } } } }
Not sure why the error occurs if I inject the
viewModel
within thesetContent
function
It vanishes because you are no longer using the compose specific methods for ViewModel. The issue is specific to using the compose viewModel() method inside compose. Moving everything out of compose kind of defeats the purpose
@racka98 I think you should update your question or show your code to make it more clear for the developers.
an update is needed regarding ViewModel API & Compose 👍
I got the same
Version
koin_version = '3.2.0'
App Log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: snipped ..., PID: 4643
java.lang.IllegalStateException: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (Start/end imbalance). Please report to Google or use https://goo.gle/compose-feedback
at androidx.compose.runtime.ComposerKt.composeRuntimeError(Composer.kt:4244)
at androidx.compose.runtime.ComposerImpl.finalizeCompose(Composer.kt:4390)
at androidx.compose.runtime.ComposerImpl.endRoot(Composer.kt:1390)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3208)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3148)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:739)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:876)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:107)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:485)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:454)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
at android.view.Choreographer.doCallbacks(Choreographer.java:899)
at android.view.Choreographer.doFrame(Choreographer.java:827)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@2e7902e, androidx.compose.ui.platform.MotionDurationScaleImpl@c1a97cf, StandaloneCoroutine{Cancelling}@aade55c, AndroidUiDispatcher@914e065]
Snipped ... Koin Log
D/[Koin]: +- '{snipped ...}.features.calculators.standard.presentation.CalculatorViewModel'
D/[Koin]: | create instance for [Factory:'{snipped ...}.features.calculators.standard.presentation.CalculatorViewModel']
D/[Koin]: +- '{snipped ...}.features.settings.domain.usecases.GetSettings'
D/[Koin]: | create instance for [Singleton:'{snipped ...}.features.settings.domain.usecases.GetSettings']
D/[Koin]: +- '{snipped ...}.core.repository.SettingsRepository'
D/[Koin]: | create instance for [Singleton:'{snipped ...}.core.repository.SettingsRepositoryImpl',binds:{ snipped ... }.core
.repository.SettingsRepository]
D/[Koin]: +- 'androidx.datastore.core.DataStore'
D/[Koin]: | create instance for [Singleton:'androidx.datastore.core.DataStore']
D/[Koin]: +- 'android.content.Context'
D/[Koin]: | create instance for [Singleton:'android.app.Application',binds:android.content.Context,android.app.Application]
D/[Koin]: |- 'android.content.Context' in 0.2217 ms
D/[Koin]: |- 'androidx.datastore.core.DataStore' in 13.4381 ms
D/[Koin]: |- '{snipped ...}.core.repository.SettingsRepository' in 15.7899 ms
D/[Koin]: |- '{snipped ...}.features.settings.domain.usecases.GetSettings' in 16.9416 ms
D/[Koin]: |- '{snipped ...}.features.calculators.standard.presentation.CalculatorViewModel' in 47.5962 ms
Edit:
That was my mistake, the assignment should be without delegation: =
instead of by
. Leaving here as a reference
I got a similar error, in a super basic composable, it crashes/got fixed by adding/removing the line #5
#1 import org.koin.androidx.compose.viewModel
#2
#3 @Composable
#4 fun HomeScreen(modifier: Modifier = Modifier) {
#5 val viewModel: HomeViewModel by viewModel()
#6 HomeScreen(state = HomeState.Idle, modifier = modifier)
#7 }
IntelliJ CE 2022.2 RC Gradle: 7.4.2 Multimodule Multiplatform project ( Compose modules are plain Jvm + Android, not KMP ) Kotin: 1.7.10 Compose: 1.3.0-alpha01 Compose compiler: 1.3.0-beta01 (edit: just tried with rc01 as well, same) Koin: 3.2.0
java.lang.IllegalStateException: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (Start/end imbalance). Please report to Google or use https://goo.gle/compose-feedback
at androidx.compose.runtime.ComposerKt.composeRuntimeError(Composer.kt:4244)
at androidx.compose.runtime.ComposerImpl.finalizeCompose(Composer.kt:4390)
at androidx.compose.runtime.ComposerImpl.endRoot(Composer.kt:1390)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3208)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3119)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:578)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:811)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:513)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1052)
at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:131)
at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:182)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:202)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:138)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:1139)
at android.view.View.dispatchAttachedToWindow(View.java:20479)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3489)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2417)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
at android.view.Choreographer.doCallbacks(Choreographer.java:796)
at android.view.Choreographer.doFrame(Choreographer.java:731)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
This might be a duplicate of #1347 and a possible workaround is to replace lazy viewModel with getViewModel
Yep, seems something to do with Lazy. I'm currently investigating on it 👍
The root cause is that we are now using closely the ViewModel API from Google and it doesn't support any kind of Lazy
or ViewModelLazy
retuned type in Compose 1.1+
Best is to use the eager API: koinViewModel()
or even get()
I will deprecate with error lazy APIs of koin-androidx-compose
in 3.2.1