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

Android Kotlin:如何获取无关联双Room表数据并通过Retrofit提交?

解决方案

方案一:使用MediatorLiveData合并数据

MediatorLiveData可以监听多个LiveData的变化,当两个数据源都就绪时,将它们封装成一个组合对象,再执行提交操作。

实现步骤:

  1. 定义封装两个列表的数据类:
data class SubmissionData(
    val karyawanList: List<KaryawanLocalEntity>,
    val absenList: List<AbsenEntity>
)
  1. 创建MediatorLiveData合并两个LiveData:
// 临时变量存储两个数据源的最新数据
private var currentKaryawanList: List<KaryawanLocalEntity>? = null
private var currentAbsenList: List<AbsenEntity>? = null

val combinedData = MediatorLiveData<SubmissionData>().apply {
    // 监听第一个LiveData
    addSource(listKaryawanLocalEntity) { list ->
        currentKaryawanList = list
        updateCombinedData()
    }
    // 监听第二个LiveData
    addSource(logAllAbsen) { list ->
        currentAbsenList = list
        updateCombinedData()
    }
}

private fun updateCombinedData() {
    val karyawan = currentKaryawanList
    val absen = currentAbsenList
    // 根据业务需求判断数据是否就绪,比如允许空列表可去掉非空判断
    if (karyawan != null && absen != null) {
        combinedData.value = SubmissionData(karyawan, absen)
    }
}
  1. 观察合并后的LiveData,发起Retrofit请求:
combinedData.observe(this) { submissionData ->
    // 用协程在后台执行提交(推荐用lifecycleScope或viewModelScope)
    lifecycleScope.launch {
        try {
            val response = apiService.submitData(submissionData)
            // 处理成功响应
        } catch (e: Exception) {
            // 处理请求异常
        }
    }
}

方案二:使用Flow的combine操作符(推荐,适配现代Kotlin协程)

如果你的Room DAO支持返回Flow(Room 2.2+默认支持),可以将LiveData转为Flow,用combine操作符合并两个数据流,代码更简洁且天然适配协程。

实现步骤:

  1. 调整Room DAO返回Flow(或直接将现有LiveData转为Flow):
// 示例DAO方法(若之前是LiveData,可改为Flow)
@Query("SELECT * FROM karyawan ORDER BY ...")
fun getDataDescLocal(): Flow<List<KaryawanLocalEntity>>

@Query("SELECT * FROM absen")
fun getAllAbsensi(): Flow<List<AbsenEntity>>
  1. 在ViewModel/Repository中合并两个Flow:
val combinedFlow = combine(
    repository.local.getDataDescLocal(),
    repository.local.getAllAbsensi()
) { karyawanList, absenList ->
    SubmissionData(karyawanList, absenList)
}
  1. 收集Flow数据并提交:
// 在Activity/Fragment的生命周期协程中收集数据
lifecycleScope.launch {
    combinedFlow.collect { submissionData ->
        // 根据业务判断是否需要提交(比如避免空数据请求)
        if (submissionData.karyawanList.isNotEmpty() || submissionData.absenList.isNotEmpty()) {
            try {
                val response = apiService.submitData(submissionData)
                // 处理成功逻辑
            } catch (e: Exception) {
                // 处理错误逻辑
            }
        }
    }
}

注意事项

  • 提交前需根据业务规则校验数据有效性,避免无效请求。
  • Retrofit请求必须在后台线程执行,务必用协程或其他异步方式,禁止在主线程调用。
  • 若仅需单次提交而非实时监听数据变化,可在获取到有效数据后取消观察/收集,避免重复提交。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:03:24