我遇到了一些问题,因为当对底层数据库表进行更改时,Room数据流不会发出更新.
API Service个
interface AtemsService {
@GET("$PATH/data/_apps.json")
suspend fun getPackageData(): Map<String, AtemsPackageInfo>
}
Remote Impl
class AtemsRemoteImpl @Inject constructor(private val atemsService: AtemsService) : AtemsRemote {
override suspend fun getAtemsPackageData(): Map<String, AtemsPackageInfo> =
atemsService.getPackageData()
}
Local Dao个
@Dao
interface AtemsPackageDao {
@Query("SELECT * FROM $TABLE_NAME")
suspend fun getAll(): List<LocalAtemsPackage>
@Upsert
suspend fun upsertAll(localAtemsPackages: List<LocalAtemsPackage>)
}
Repo Impl个
class AtemsPackageRepositoryImpl @Inject constructor(
private val atemsRemote: AtemsRemote,
private val atemsPackageDao: AtemsPackageDao,
private val atemsPackageMapper: AtemsPackageMapper,
) : AtemsPackageRepository {
override fun observeAtemsPackages(): Flow<List<AtemsPackage>> {
return flow {
val localAtemsPackages = atemsPackageDao.getAll()
emit(atemsPackageMapper.localToDomain(localAtemsPackages))
if (localAtemsPackages.isEmpty()) {
val fetchRemotePackages = atemsRemote.getAtemsPackageData()
val convertToLocal = atemsPackageMapper.remoteToLocal(fetchRemotePackages)
atemsPackageDao.upsertAll(convertToLocal)
}
}
}
}
Use Case个
class AppsUseCaseImpl @Inject constructor(
atemsPackageRepository: AtemsPackageRepository,
) : AppsUseCase {
override val observeApps: Flow<List<AtemsPackage>> = atemsPackageRepository.observeAtemsPackages()
}
View Model
@HiltViewModel
class SidePanelAppListViewModel @Inject constructor(appsUseCase: AppsUseCase) : ViewModel() {
val apps = appsUseCase.observeApps.stateIn(
scope = viewModelScope,
started = WhileUiSubscribed,
initialValue = emptyList()
)
}
最后, View
@Composable
fun SidePanelAppList(
modifier: Modifier = Modifier,
viewModel: SidePanelAppListViewModel = hiltViewModel(),
) {
val apps by viewModel.apps.collectAsStateWithLifecycle()
SidePanelAppList(
modifier = Modifier.then(modifier),
apps = apps
)
}
除了repo中的方法进行网络调用以检索数据之外,一切都按预期进行,尽管成功地将数据保存到Room数据库,但除非应用程序重新启动,否则我的用户界面层不会收集/显示更新.任何指导都将不胜感激!
Update
遵循Tenour04非常有用的正确方向,我完成了这个(需求略有变化,因为我现在根据从遥控器检索到的值进行更新.
@OptIn(ExperimentalCoroutinesApi::class)
override fun observeAtemsPackages(): Flow<List<AtemsPackage>> =
atemsPackageDao.observeAll().transformLatest {
val lastLocalUpdate = settingsDataStore.getAtemsRemoteLastUpdate.first()
val lastRemoteUpdate = atemsRepoRemote.getAtemsLastUpdate().lastUpdated
if (lastRemoteUpdate > lastLocalUpdate) {
val fetchRemotePackages = atemsRepoRemote.getAtemsPackageData()
val convertToLocal = atemsPackageMapper.remoteToLocal(fetchRemotePackages)
atemsPackageDao.upsertAll(convertToLocal)
settingsDataStore.setAtemsRemoteLastUpdate(lastRemoteUpdate)
}
emit(atemsPackageMapper.localToDomain(it))
}