升级Navigation3相关依赖后ViewModel的onCleared()方法不再调用的问题求助
大家好,我最近升级了几个Navigation3相关的依赖包,结果遇到了一个棘手的问题:ViewModel里的onCleared()方法突然不触发了!之前用旧版本的时候一切正常,升级之后就不行了,想请教下有没有人遇到过类似情况,或者能给我一些解决思路?
依赖升级详情
我更新的依赖项是这几个:
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "nav3Core" } androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "nav3Core" } androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "lifecycleViewmodelNav3" }
版本从下面的旧版:
nav3Core = "1.0.0-alpha03" lifecycleViewmodelNav3 = "1.0.0-alpha01"
升级到了新版:
nav3Core = "1.0.0-alpha04" lifecycleViewmodelNav3 = "1.0.0-alpha02"
为了定位问题,我已经把代码简化到最小复现的程度——只有两个页面,点击按钮完成页面跳转,但onCleared()依然不被调用。下面是相关代码:
导航逻辑代码
@Composable fun AppNavDisplay( backStack: NavBackStack ) { NavDisplay( entryDecorators = listOf( rememberSceneSetupNavEntryDecorator(), rememberSavedStateNavEntryDecorator(), rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = entryProvider { entry<Screen.SignIn> { SignInScreen( onClearAndNavigate = backStack::onClearAndNavigate ) } entry<Screen.Main> { MainScreen( onClearAndNavigate = backStack::onClearAndNavigate ) } } ) } fun NavBackStack.onClearAndNavigate(screen: Screen) { clear() add(screen) }
SignInViewModel代码
这里重写了onCleared()方法,日志打不出来,说明根本没被调用:
class SignInViewModel( private val repo: AuthRepository ): ViewModel() { val signInState = ResponseStateHandler<Unit>() fun signIn() = viewModelScope.launch { try { signInState.setLoading() repo.signIn() signInState.setSuccess(Unit) } catch (e: Exception) { signInState.setFailure(e.message!!) } } override fun onCleared() { Log.d(TAG, "signInViewModel.onCleared") // 此处无日志输出 signInState.setIdle() } }
页面UI代码
登录页面的UI,点击按钮触发登录逻辑,成功后跳转到主页面:
Scaffold( modifier = Modifier.fillMaxSize() ) { innerPadding -> Box( modifier = Modifier.fillMaxSize().padding(innerPadding), contentAlignment = Alignment.Center ) { Button( onClick = viewModel::signIn, enabled = !isProcessing ) { Row( verticalAlignment = Alignment.CenterVertically ) { Text( text = "SignIn" ) Spacer( modifier = Modifier.width(4.dp) ) if (isProcessing) { CircularProgressIndicator( modifier = Modifier.size(12.dp), strokeWidth = 2.dp ) } } } } }
主页面的UI,点击按钮退出登录,跳转回登录页面:
val isUserSignedOut by viewModel.isSignedOutState.collectAsStateWithLifecycle() LaunchedEffect(isUserSignedOut) { if (isUserSignedOut) { onClearAndNavigate(Screen.SignIn) } } Scaffold( modifier = Modifier.fillMaxSize() ) { innerPadding -> Box( modifier = Modifier.fillMaxSize().padding(innerPadding), contentAlignment = Alignment.BottomCenter ) { Row( verticalAlignment = Alignment.CenterVertically ) { Button( onClick = viewModel::deleteUser, enabled = !isProcessing ) { Text( text = "SignOut" ) Spacer( modifier = Modifier.width(4.dp) ) if (isProcessing) { CircularProgressIndicator( modifier = Modifier.size(12.dp), strokeWidth = 2.dp ) } } } } }
Screen路由定义
sealed interface Screen: NavKey { @Serializable data object Main : Screen @Serializable data object SignIn : Screen }
我反复测试过,只要把依赖回退到旧版本,onCleared()就会正常触发,所以问题肯定出在这次依赖升级上。有没有大佬知道这是新版本的bug,还是我需要调整什么代码逻辑?麻烦指点一下,谢谢!
内容来源于stack exchange
相关产品推荐
相关产品推荐

