#android #android-livedata #kotlin-coroutines #android-viewmodel #android-livedata-transformations
Вопрос:
У меня есть функция IOTCamera внутри ViewModel с циклом. Функция должна повторно вызывать функцию GET репозитория на основе параметра «selectedSlot» с задержкой в 1 минуту. Моя проблема здесь в том, что цикл(повтор()) работает неправильно. Это работает для первой итерации. Но вторая итерация никогда не вызывается.
fun getIOTCameraData(repository: MainRepository, selectedSlot: Int)= viewModelScope.launch(Dispatchers.Default){
repeat(selectedSlot){
repository.getIOTCameraData(1, 10).asFlow().collect {data->
if (responseStatusIdentification(data)) {
_iotCameraData.postValue(data.data)//Update live data instance for UI
}
}
delay(60000)
}
}
Функция репозитория вызовет API Retrofit GET, и он будет собирать данные.
suspend fun getIOTCameraData(page: Int, perPage: Int) = liveData<Resource<IOTCameraResponse>> {
emit(Resource.loading())
try {
val response = iotCameraService?.getIOTCameraData(token = IOT_CAMERA_AUTH, page = page, perPage = perPage)
emit(Resource.success(response))
} catch (e: Exception) {
emit(Resource.error(e.message.toString()))
}
}
Пожалуйста, обновите, если кто-нибудь знает причину этого.
Ответ №1:
Призыв collect
никогда не возвращается. Если вам просто нужно получить одно значение и завершить сбор, вам следует позвонить first()
вместо этого.
Подобный этому:
val data = repository.getIOTCameraData(1, 10).asFlow().first {
responseStatusIdentification(it)
}
_iotCameraData.postValue(data.data)
Комментарии:
1. Но в этом случае функция getIOTCameraData suspend может выдавать два раза. Первым сообщением будет статус загрузки, а оставшимся — либо успех, либо ошибка в HTTP — ответе. Функция responseStatusIdentification() фактически обрабатывает состояние загрузки. Поэтому мой вопрос в том, вернется ли .first() дважды?
2. Оператор терминала возвращает первый элемент, испускаемый потоком, а затем отменяет сбор потока. В моем понимании,. first() отменит оставшиеся потоки.
3. Я отредактировал свой ответ, чтобы отфильтровать неудачный ответ. Я изобрел
isSucces
свойство для этого, но, возможно, это вашаresponseStatusIdentification()
функция. ПРАВКА: Я только что предположил это.4. Я могу быть немного лучше, просто используя
first()
функцию, которая принимает предикат… Я отредактирую ответ =)