You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Navigation3相关依赖后ViewModel的onCleared()方法不再调用的问题求助

升级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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 09:37:59