Jetpack 撰写 BottomNavigation - java.lang.IllegalStateException:已附加到 lifecycleOwner
Jetpack compose BottomNavigation - java.lang.IllegalStateException: Already attached to lifecycleOwner
当我双击同一个项目或者如果我很快转到每个可组合屏幕时我收到错误消息,我该如何解决这个问题?我尝试改变一些东西,但我无法解决它,我找不到任何资源来解决这个问题。
底部导航实现
@Composable
fun BottomNav(
navController: NavController,
bottomNavState: MutableState<Boolean>,
) {
val navItems = listOf(
Screen.HomeScreen,
Screen.BookmarkScreen,
Screen.MyRecipesScreen,
Screen.FavouriteScreen
)
AnimatedVisibility(
visible = bottomNavState.value,
enter = slideInVertically(initialOffsetY = { it }),
exit = slideOutVertically(targetOffsetY = { it }),
content = {
BottomNavigation(
backgroundColor = Color.White,
elevation = 12.dp
) {
val bottomNavBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = bottomNavBackStackEntry?.destination
navItems.forEach { item ->
BottomNavigationItem(
icon = {
Icon(painter = painterResource(id = item.icon), contentDescription = "")
},
label = {
Text(text = item.title)
},
selected = currentDestination?.hierarchy?.any { it.route == item.route } == true,
onClick = {
navController.navigate(item.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
},
selectedContentColor = Color.Black,
unselectedContentColor = Color.LightGray,
alwaysShowLabel = true,
)
}
}
}
)
}
收到错误
2022-03-05 11:50:10.183 8460-8460/com.im.cookgaloreapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.im.cookgaloreapp, PID: 8460
java.lang.IllegalStateException: Already attached to lifecycleOwner
at androidx.lifecycle.SavedStateHandleController.attachToLifecycle(SavedStateHandleController.java:38)
at androidx.lifecycle.SavedStateHandleAttacher.onRecreated(SavedStateHandleSupport.kt:139)
at androidx.savedstate.Recreator.reflectiveNew(Recreator.java:90)
at androidx.savedstate.Recreator.onStateChanged(Recreator.java:62)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.java:121)
at androidx.navigation.NavBackStackEntry.updateState(NavBackStackEntry.kt:188)
at androidx.navigation.NavBackStackEntry.setMaxLifecycle(NavBackStackEntry.kt:154)
at androidx.navigation.NavController.updateBackStackLifecycle$navigation_runtime_release(NavController.kt:987)
at androidx.navigation.NavController.dispatchOnDestinationChanged(NavController.kt:892)
at androidx.navigation.NavController.navigate(NavController.kt:1726)
at androidx.navigation.NavController.navigate(NavController.kt:1658)
at androidx.navigation.NavController.navigate(NavController.kt:1980)
at androidx.navigation.NavController.navigate$default(NavController.kt:1975)
at androidx.navigation.NavController.navigate(NavController.kt:1961)
at com.im.cookgaloreapp.ui.components.BottomNavigationKt$BottomNav.invoke(BottomNavigation.kt:67)
at com.im.cookgaloreapp.ui.components.BottomNavigationKt$BottomNav.invoke(BottomNavigation.kt:57)
at androidx.compose.foundation.ClickableKt$clickable$gesture.invoke-k-4lQ0M(Clickable.kt:153)
at androidx.compose.foundation.ClickableKt$clickable$gesture.invoke(Clickable.kt:142)
at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress.invokeSuspend(TapGestureDetector.kt:223)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:328)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:511)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.dispatchPointerEvent(SuspendingPointerInputFilter.kt:406)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:419)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:310)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:179)
at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:98)
at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:80)
2022-03-05 11:50:10.184 8460-8460/com.im.cookgaloreapp E/AndroidRuntime: at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1205)
at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1155)
at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1095)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:488)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1871)
at android.app.Activity.dispatchTouchEvent(Activity.java:4125)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:446)
at android.view.View.dispatchPointerEvent(View.java:14568)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6016)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5819)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5310)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5367)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5333)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5485)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5341)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5542)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5314)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5367)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5333)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5341)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5314)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8080)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8031)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7992)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8203)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:220)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:335)
at android.os.Looper.loop(Looper.java:183)
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)
我在使用最新的 compose 导航依赖项时遇到了同样的问题 2.5.0-alpha03
。
我不知道为什么会这样。
Philip Dukhov 说得对,你应该报告这个问题。
这是一个肮脏的解决方法:
try {
// The navigation code that throw this exception
} catch (e: IllegalStateException) {
if (e.message != "Already attached to lifecycleOwner") {
throw e
} else {
// You can log the exception if you want
}
}
这确实是导航错误。问题是 Tab 被反复点击。暂时的解决办法是return均等
NavigationBarItem(
icon = {
Icon(painterResource(id = screen.icon), contentDescription = screen.route)
},
selected = currentRoute == screen.route,
onClick = {
if (currentRoute == screen.route) {
return@NavigationBarItem
}
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
2.5.0-alpha03确实存在bug。汇款到2.5.0-alpha02修复了bug
implementation 'androidx.navigation:navigation-compose:2.5.0-alpha03'
至
implementation 'androidx.navigation:navigation-compose:2.5.0-alpha02'
帮我修好了
我在 2.5.0-alpha01
、2.5.0-alpha02
和 2.5.0-alpha03
中遇到了相同的错误,但最终能够在 2.5.0-alpha04
中使用它。第四次就是魅力!
当我双击同一个项目或者如果我很快转到每个可组合屏幕时我收到错误消息,我该如何解决这个问题?我尝试改变一些东西,但我无法解决它,我找不到任何资源来解决这个问题。
底部导航实现
@Composable
fun BottomNav(
navController: NavController,
bottomNavState: MutableState<Boolean>,
) {
val navItems = listOf(
Screen.HomeScreen,
Screen.BookmarkScreen,
Screen.MyRecipesScreen,
Screen.FavouriteScreen
)
AnimatedVisibility(
visible = bottomNavState.value,
enter = slideInVertically(initialOffsetY = { it }),
exit = slideOutVertically(targetOffsetY = { it }),
content = {
BottomNavigation(
backgroundColor = Color.White,
elevation = 12.dp
) {
val bottomNavBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = bottomNavBackStackEntry?.destination
navItems.forEach { item ->
BottomNavigationItem(
icon = {
Icon(painter = painterResource(id = item.icon), contentDescription = "")
},
label = {
Text(text = item.title)
},
selected = currentDestination?.hierarchy?.any { it.route == item.route } == true,
onClick = {
navController.navigate(item.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
},
selectedContentColor = Color.Black,
unselectedContentColor = Color.LightGray,
alwaysShowLabel = true,
)
}
}
}
)
}
收到错误
2022-03-05 11:50:10.183 8460-8460/com.im.cookgaloreapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.im.cookgaloreapp, PID: 8460
java.lang.IllegalStateException: Already attached to lifecycleOwner
at androidx.lifecycle.SavedStateHandleController.attachToLifecycle(SavedStateHandleController.java:38)
at androidx.lifecycle.SavedStateHandleAttacher.onRecreated(SavedStateHandleSupport.kt:139)
at androidx.savedstate.Recreator.reflectiveNew(Recreator.java:90)
at androidx.savedstate.Recreator.onStateChanged(Recreator.java:62)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.java:121)
at androidx.navigation.NavBackStackEntry.updateState(NavBackStackEntry.kt:188)
at androidx.navigation.NavBackStackEntry.setMaxLifecycle(NavBackStackEntry.kt:154)
at androidx.navigation.NavController.updateBackStackLifecycle$navigation_runtime_release(NavController.kt:987)
at androidx.navigation.NavController.dispatchOnDestinationChanged(NavController.kt:892)
at androidx.navigation.NavController.navigate(NavController.kt:1726)
at androidx.navigation.NavController.navigate(NavController.kt:1658)
at androidx.navigation.NavController.navigate(NavController.kt:1980)
at androidx.navigation.NavController.navigate$default(NavController.kt:1975)
at androidx.navigation.NavController.navigate(NavController.kt:1961)
at com.im.cookgaloreapp.ui.components.BottomNavigationKt$BottomNav.invoke(BottomNavigation.kt:67)
at com.im.cookgaloreapp.ui.components.BottomNavigationKt$BottomNav.invoke(BottomNavigation.kt:57)
at androidx.compose.foundation.ClickableKt$clickable$gesture.invoke-k-4lQ0M(Clickable.kt:153)
at androidx.compose.foundation.ClickableKt$clickable$gesture.invoke(Clickable.kt:142)
at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress.invokeSuspend(TapGestureDetector.kt:223)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:328)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:511)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.dispatchPointerEvent(SuspendingPointerInputFilter.kt:406)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:419)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:310)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:179)
at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:98)
at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:80)
2022-03-05 11:50:10.184 8460-8460/com.im.cookgaloreapp E/AndroidRuntime: at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1205)
at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1155)
at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1095)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3118)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2799)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:488)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1871)
at android.app.Activity.dispatchTouchEvent(Activity.java:4125)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:446)
at android.view.View.dispatchPointerEvent(View.java:14568)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6016)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5819)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5310)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5367)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5333)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5485)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5341)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5542)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5314)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5367)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5333)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5341)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5314)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8080)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8031)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7992)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8203)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:220)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:335)
at android.os.Looper.loop(Looper.java:183)
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)
我在使用最新的 compose 导航依赖项时遇到了同样的问题 2.5.0-alpha03
。
我不知道为什么会这样。
Philip Dukhov 说得对,你应该报告这个问题。
这是一个肮脏的解决方法:
try {
// The navigation code that throw this exception
} catch (e: IllegalStateException) {
if (e.message != "Already attached to lifecycleOwner") {
throw e
} else {
// You can log the exception if you want
}
}
这确实是导航错误。问题是 Tab 被反复点击。暂时的解决办法是return均等
NavigationBarItem(
icon = {
Icon(painterResource(id = screen.icon), contentDescription = screen.route)
},
selected = currentRoute == screen.route,
onClick = {
if (currentRoute == screen.route) {
return@NavigationBarItem
}
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
2.5.0-alpha03确实存在bug。汇款到2.5.0-alpha02修复了bug
implementation 'androidx.navigation:navigation-compose:2.5.0-alpha03'
至
implementation 'androidx.navigation:navigation-compose:2.5.0-alpha02'
帮我修好了
我在 2.5.0-alpha01
、2.5.0-alpha02
和 2.5.0-alpha03
中遇到了相同的错误,但最终能够在 2.5.0-alpha04
中使用它。第四次就是魅力!