Android Compose登录后StateFlow持续发射导致无法返回问题排查
问题根因
你使用StateFlow<Boolean>存储导航触发状态,登录成功将_navigateToDashboard赋值为true后未做重置操作。Compose会高频触发页面重组,只要navigateToDashboard的值保持为true,每次重组都会执行导航逻辑,因此会持续打印called日志,同时反复执行popBackStack和跳转首页操作,最终导致无法正常返回上一级页面。
修复方案
方案1:手动重置导航状态(改动最小,适配现有代码)
- 先在ViewModel中新增重置导航状态的方法:
// AuthViewModel.kt 新增代码 fun resetNavigationState() { _navigateToDashboard.value = false }
- 在Login Screen的导航逻辑执行完成后,立刻调用重置方法:
if (navigateToDashboard) { Timber.e("called") navController.popBackStack() navController.navigate("home") // 新增该行重置状态,避免后续重组重复触发导航 authViewModel.resetNavigationState() }
方案2:改用SharedFlow承载一次性导航事件(更规范的实现)
导航属于一次性消费事件,本身不需要留存状态,用SharedFlow实现更合理,不需要手动处理重置逻辑:
- 修改ViewModel中的导航相关定义:
// 替换原有的navigateToDashboard StateFlow定义 private val _navigateToDashboard = MutableSharedFlow<Unit>() val navigateToDashboard: SharedFlow<Unit> = _navigateToDashboard // 登录成功处的赋值改为发射事件 fun loginUser() { viewModelScope.launch(Dispatchers.IO) { isLoading.value = true try { val response = repo.loginUsers(email = email.value, password = password.value) pref.storePrefValue(UserPreferences.token, response.data?.authToken ?: "") pref.storePrefValue( UserPreferences.loginData, AppUtility.modelToJson(response) ?: "" ) isLoading.value = false // 替换原有的_navigateToDashboard.value = true _navigateToDashboard.emit(Unit) Timber.e("ho") } catch (exception: Exception) { isLoading.value = false Timber.e(exception) } } }
- 修改Login Screen中的事件监听逻辑:
// 替换原有的navigateToDashboard collectAsState 监听逻辑 LaunchedEffect(Unit) { authViewModel.navigateToDashboard.collect { Timber.e("called") navController.popBackStack() navController.navigate("home") } }
内容的提问来源于stack exchange,提问作者Anuj
相关产品推荐
相关产品推荐

