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

如何创建订阅支持延迟启动的Kotlin Flow,实现登录令牌循环刷新

实现方案

核心思路是通过状态流控制刷新逻辑的启停,配合Kotlin Flow的flatMapLatest操作符实现条件触发,同时保留Android生命周期绑定的自动停止特性。


1. 改造刷新令牌UseCase

保留原有冷流实现,仅做小的稳定性优化:

RefreshTokenUseCase.kt
class RefreshTokenUseCase {
    // 冷流特性:只有被收集时才会执行内部循环逻辑
    fun tokenRefresh(pollingIntervalMs: Long = 5000): Flow<RefreshResult> = flow {
        // 用协程上下文活跃状态判断替代while(true),更安全
        while (currentCoroutineContext().isActive) {
            delay(pollingIntervalMs)
            val res = refreshToken(userToken)
            emit(res)
        }
    }
}

2. 实现ViewModel控制逻辑

新增状态开关控制刷新启停,通过流变换实现逻辑解耦:

SomeViewModel.kt
class SomeViewModel(
    private val refreshTokenUseCase: RefreshTokenUseCase
) : ViewModel() {
    // 刷新功能开关,初始为关闭状态
    private val _isRefreshEnabled = MutableStateFlow(false)
    
    // 对外暴露的登出错误流
    val loggedOutError: Flow<RefreshResult> = _isRefreshEnabled
        // 开关状态变更时切换对应的流
        .flatMapLatest { isEnabled ->
            if (isEnabled) {
                // 开关打开时,启动刷新流并过滤过期错误
                refreshTokenUseCase.tokenRefresh()
                    .filter { it == TokenExpired }
            } else {
                // 开关关闭时返回空流,不产生任何事件
                emptyFlow()
            }
        }
        // 配置为共享流,避免配置变更后重复消费事件
        .shareIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5000),
            replay = 0
        )

    fun userHasLoggedIn() {
        // 打开刷新开关,自动启动刷新逻辑
        _isRefreshEnabled.update { true }
    }

    // 可选扩展:登出时关闭刷新
    fun userHasLoggedOut() {
        _isRefreshEnabled.update { false }
    }
}

3. 视图层收集逻辑

推荐用官方更推荐的repeatOnLifecycle替代launchWhenStarted,避免后台回调问题:

SomeFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewLifecycleOwner.lifecycleScope.launch {
        // 仅在视图处于STARTED及以上生命周期时收集流
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            viewModel.loggedOutError.collect {
                showLoggedOutError()
            }
        }
    }
}

方案优势

  • 启动时机可控:初始化阶段刷新逻辑完全休眠,只有主动调用userHasLoggedIn后才会启动刷新
  • 自动生命周期管理:视图退到后台时自动停止收集,刷新协程自动取消,回到前台后自动恢复
  • 无手动协程管理:所有逻辑通过Flow原生操作符实现,避免手动维护Job导致的内存泄漏或重复执行问题
  • 边界处理完善:登出时只要关闭开关即可立刻停止刷新,多次调用启动方法不会重复创建刷新任务

内容的提问来源于stack exchange,提问作者Daniel Dudek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:36:04