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

Android领域层:如何用单个UseCase整合本地与远程数据逻辑

整合Android领域层用例的解决方案

核心思路

要实现「仅返回一次本地数据Flow,后续仅触发远程更新」的需求,关键是把Flow提供和远程刷新操作分离:用例内部维护持续的本地数据Flow,单独提供触发远程同步的方法,避免每次刷新都生成新Flow。

方案1:封装为带刷新方法的用例类

将用例设计成类,内部初始化一次本地数据Flow,通过独立的refresh()方法触发远程获取与本地存储。

class GetReportUseCase(
    private val reportRepository: ReportRepository
) {
    // 仅初始化一次本地数据Flow,后续复用同一个实例
    val reportFlow: Flow<Report> = reportRepository.getFromLocal()

    // 触发远程数据更新的挂起方法
    suspend fun refresh() {
        // 拉取远程数据并存储到本地,本地Flow会自动感知数据变化并发射新值
        val remoteReport = reportRepository.getFromRemote()
        reportRepository.saveToLocal(remoteReport)
    }
}

ViewModel侧使用示例

class ReportViewModel(
    private val getReportUseCase: GetReportUseCase
) : ViewModel() {
    // 将冷Flow转为热StateFlow,确保配置变化时不重新收集
    val reportState = getReportUseCase.reportFlow
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5000),
            initialValue = Report.Empty
        )

    // 用户触发刷新时调用
    fun onRefresh() {
        viewModelScope.launch {
            getReportUseCase.refresh()
        }
    }
}

UI只需收集reportState一次,每次调用onRefresh()时,用例会触发远程更新,本地数据变化后Flow自动通知UI刷新。

方案2:结合热Flow的invoke实现(可选)

如果坚持用operator invoke返回Flow,可将本地冷Flow转为热StateFlow,确保每次调用返回同一个实例:

class GetReportUseCase(
    private val reportRepository: ReportRepository,
    private val coroutineScope: CoroutineScope
) {
    private val _reportState = MutableStateFlow<Report>(Report.Empty)
    val reportState: StateFlow<Report> = _reportState.asStateFlow()

    init {
        // 初始化时订阅本地数据变化,自动更新StateFlow
        coroutineScope.launch {
            reportRepository.getFromLocal()
                .collect { _reportState.value = it }
        }
    }

    operator fun invoke(): StateFlow<Report> {
        return reportState
    }

    suspend fun refresh() {
        val remoteReport = reportRepository.getFromRemote()
        reportRepository.saveToLocal(remoteReport)
        // 本地数据更新后,上面的collect会自动同步到StateFlow
    }
}

关键注意事项

  • 确保getFromLocal()返回的是冷Flow(比如Room的查询Flow),这样本地数据变化时会自动发射新值。
  • refresh()必须是挂起函数,避免在主线程执行远程请求等耗时操作。
  • ViewModel中使用stateIn转换Flow,保证页面旋转等配置变化后,数据收集不会中断或重复初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:15:19