在使用 Accompanist AnimatedNavHost 和导航动画时,如果我转到一个屏幕然后连续几次快速返回(使用系统后退按钮),应用程序就会崩溃。我怀疑这是 Accompanist 中的一个错误(我已经在 Github repo 上提交了一个问题),但我认为它也值得在这里发布,以防其他人看到这个和/或有解决方法。
该应用程序因以下堆栈跟踪而崩溃:
java.util.NoSuchElementException: List contains no element matching the predicate.
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$finalEnter$1$1.invoke(AnimatedNavHost.kt:341)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$finalEnter$1$1.invoke(AnimatedNavHost.kt:173)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$7$1.invoke(AnimatedNavHost.kt:244)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$7$1.invoke(AnimatedNavHost.kt:244)
at androidx.compose.animation.AnimatedContentKt.AnimatedContent(AnimatedContent.kt:664)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:242)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$10.invoke(Unknown Source:23)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$10.invoke(Unknown Source:10)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:140)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2158)
at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2404)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2585)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2571)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotState.kt:571)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2571)
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:965)
at android.view.Choreographer.doCallbacks(Choreographer.java:791)
at android.view.Choreographer.doFrame(Choreographer.java:722)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
我的导航代码如下:
AnimatedNavHost(navController = navController, startDestination = startDestinationString) {
composable(
route = "home",
) {
HomeScreen(
homeViewModel = homeViewModel,
navigateToBookDetail = { book ->
val arguments =
Bundle().apply {
putParcelable("book", book)
}
navController.navigate(route = "book_detail", args = arguments)
}
)
}
composable(
route = "book_detail",
enterTransition = { _, _ ->
slideInHorizontally(initialOffsetX = { 1500 }, animationSpec = tween(250))
},
popExitTransition = { _, _ ->
slideOutHorizontally(targetOffsetX = { 1500 }, animationSpec = tween(250))
}
) { backstackEntry ->
val book = backstackEntry.arguments?.getParcelable<Book>("book")
if (book != null) {
BookDetailScreen(viewModel = bookDetailViewModel, book = book)
}
}
}
重现
在两个屏幕之间快速导航,在动画完成之前使用系统后退按钮返回到第一个屏幕。就我而言,我正在触发动画并在动画完成之前使用系统后退按钮。这通常需要几次尝试才能崩溃。有时只有两个,有时五个或十个。
0.21.0-beta 版伴奏动画导航