android 从后台到前台应用程序,流量收集观察到的数据多次更改

2cmtqfgy  于 6个月前  发布在  Android
关注(0)|答案(1)|浏览(69)

我使用了Kotlinflow进行API调用。在viewModel中,将stateFlow暴露给Activity以观察数据变化。
当我启动应用程序时,API被命中,在Activity中成功获取数据和收集流量。

  • 问题是当我保持应用在后台并在5秒后打开时,API再次被击中。我不想再次击中API,因为我已经收集了流量。*

有没有人能帮上忙,怎样才能达到预期的行为?
视图模型:

class FlowViewModel(
    dataSource: DataSource
) : BaseViewModel<UiState>() {

    val priceFlow: StateFlow<UiState> = dataSource
        .apiCall
        .onStart {
            Timber.tag("Flow").d("Flow has started.")
        }
        .map { stockList ->
            UiState.Success(list) as UiState
        }
        .onCompletion {
            Timber.tag("Flow").d("Flow has completed.")
        }.stateIn(
            scope = viewModelScope,
            initialValue = UiState.Loading,
            started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000)
        )
}

字符串
在Activity中收集流量,如下所示:

lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.priceFlow.collect { uiState ->
                    render(uiState)
                }
            }
        }


无法在此处添加整个dataSource类我添加了mock DataSource以供参考。

class DataSource(mockApi: MockApi) : BaseDataSource {

    override val apiCall: Flow<List<Price>> = flow {
            val currentStockList = mockApi.getCurrentPrices()
            emit(currentStockList)
        }
    }
}

iq3niunx

iq3niunx1#

使用savedStateHandle在进程死亡期间持久化UI元素的数据,并在进行API调用之前检查它们的值。为此使用init块。
视图模型:

class FlowViewModel(
    val savedStateHandle: SavedStateHandle,
    dataSource: DataSource
) : BaseViewModel<UiState>() {

private val _uiState: MutableStateFlow<UiState?> = MutableStateFlow(null)
val uiState = _uiState.asStateFlow()
val priceFlow = savedStateHandle.getStateFlow("priceFlow", emptyList<String>())

init {
  if(priceFlow.value.isEmpty()){
    callApi()
  }
}

fun callApi(){
  viewModelScope.launch {
    _uiState.emit(dataSource.apiCall())
  }
}

fun updatePrice(priceList: List<String>){
  savedStateHandle["priceFlow"] = priceList
}
}

字符串
活动:

val priceList = viewModel.priceFlow.collectAsState().value

lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            viewModel.uiState.collect { uiState ->
                when(uiState){
                   is UiState.Success -> {
                      viewModel.updatePrice(uiState.data)
                   }
                   ...
                }
            }
        }
    }

相关问题