一键跳转页面并删除原页面数据时应用崩溃问题求助
解决Room删除数据后跳转页面崩溃问题
问题场景
在Tournament视图中执行删除当前赛事操作后跳转至MainScreen,遇到两个异常情况:
- 直接启动协程执行删除后立刻跳转,数据能成功删除,但应用崩溃——原因是删除操作未完成时,当前视图仍在尝试访问已删除的数据。
- 尝试在协程中添加
delay()后,数据无法被删除。
当前代码:
BottomMenu( tournamentOption = "END TOURNAMENT", deleteButton = true, deleteTournament = { scope.launch { viewModel.deleteTournament(tournament) } navigate(navController, Screen.MainScreen) }, action = { navigate(navController, Screen.MainScreen) }, )
解决方案
核心逻辑是确保删除操作完全完成后,再执行页面跳转,禁止跳转与删除异步并行。
修正后的代码
BottomMenu( tournamentOption = "END TOURNAMENT", deleteButton = true, deleteTournament = { scope.launch { // 等待删除操作执行完毕(deleteTournament为挂起函数) viewModel.deleteTournament(tournament) // 确认删除完成后再执行跳转 navigate(navController, Screen.MainScreen) } }, action = { navigate(navController, Screen.MainScreen) }, )
原因说明
- 原代码中,
launch启动协程执行删除后立刻同步调用navigate,此时删除操作可能仍在后台执行,而Tournament视图尚未销毁,仍在绑定已删除的赛事数据,最终因数据不存在引发崩溃。 - 之前添加
delay()无效的原因大概率是延迟位置错误(如放在协程外部),或页面跳转导致协程被提前取消,删除操作未执行完成。依赖固定时长的延迟不可靠,不同设备的数据库操作速度存在差异,正确做法是等待挂起函数执行完毕。
额外注意事项
- 确保使用的
scope是生命周期安全的协程作用域:比如Composable中使用rememberCoroutineScope(),ViewModel中使用viewModelScope,避免协程因页面销毁被提前取消,导致删除操作中断。 - 确认
deleteTournament是挂起函数:Room的DAO删除方法标记为suspend后,会自动在后台线程执行并挂起直到完成。
内容的提问来源于stack exchange,提问作者xMaster
相关产品推荐
相关产品推荐

