Версия Home API Kotlin использует потоки — функцию языка Kotlin, которая предоставляет мощные возможности для обработки асинхронных потоков данных, включая преобразование, фильтрацию, сопоставление, преобразование в коллекции и обратно и т. д.
Сопрограммы тесно связаны с потоками и предоставляют элегантную абстракцию для написания асинхронного кода и освобождают разработчика от необходимости явно писать процедуры обратного вызова. Потоки работают рука об руку с сопрограммами, служа способом асинхронного получения данных из сопрограмм, без необходимости ждать завершения функции или потока.
Данные извлекаются из потока потребителем в процессе, называемом сбором . В потоках Kotlin есть функция collect()
, которую можно использовать для этой цели. То, что происходит в потоке во время сбора данных, зависит от типа потока.
Потоки Kotlin ( Flow<T>
) по умолчанию являются холодными , а это означает, что код построителя потоков создает данные только при вызове collect()
. Горячий поток, напротив, создает данные немедленно, буферизуя их в памяти, как очередь, на случай, если данные будут использованы. Поскольку данные хранятся в памяти, горячий поток считается сохраняющим состояние.
Потоки можно преобразовать из холодных в горячие с помощью оператора shareIn
(см. «Как сделать холодные потоки горячими с помощью shareIn
»). Вы также можете использовать SharedFlow
или StateFlow
, чтобы превратить холодный поток в горячий.
Как пример приложения использует потоки
В примере приложения используются модели представлений в Jetpack Compose, подключенные к потокам Home API. Многие из примеров элементов пользовательского интерфейса приложения управляются состоянием, но с ними можно взаимодействовать. Пример приложения также сочетает состояние устройств с «оптимистическим» состоянием пользовательского интерфейса для удобства работы пользователя в реальном времени. Термин «оптимистичный» означает, что приложение предполагает, что данное действие выполнено успешно, и немедленно обновляет пользовательский интерфейс, чтобы отразить ожидаемый результат, не дожидаясь подтверждения. Если окажется, что действие не удалось, пользовательский интерфейс обновляется, чтобы отразить истинное состояние.
В примере приложения потоки создаются для каждого уровня модели представления (структур, помещений, устройств). Например, это делается для структур со следующим вызовом в GlobalViewModel.kt
:
fun getStructuresState(): StateFlow<List<StructureModel>?> =
homeClient
.structures()
.map { structures -> structures.map { StructureModel(it.name, it) }.sortedBy { it.name } }
.handleErrors()
.flowOn(Dispatchers.IO)
.stateIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(), null)
emitAll()
собирает все значения из данного потока и отправляет их в сборщик. stateIn()
передает последнее переданное значение из одного работающего экземпляра восходящего потока нескольким нисходящим подписчикам. Дополнительную информацию см. в справочнике kotlinx.coroutines.flow
.
Реактивный ранец
Чтобы хранить объекты потока в локальной памяти и предотвратить их завершение, используйте API remember
Kotlin.
В Jetpack Compose, если вы используете это с collectAsStateWithLifecycle()
, Jetpack автоматически управляет подпиской и отменой подписки на потоки в зависимости от того, находится ли пользовательский интерфейс приложения, показывающий это состояние, на переднем плане или нет.
Это можно сделать с помощью простого вызова в примере приложения. Использование функции getStructuresState()
показанной ранее:
val structuresList by
remember(globalViewModel) { globalViewModel.getStructuresState() }.collectAsStateWithLifecycle()
Теперь, когда какое-либо состояние структуры изменится (например, name
), функция Composable, которая его использует, автоматически отразит это обновленное состояние. В примере приложения это функция HomeActivityContent()
.
Ресурсы
Дополнительную информацию о Kotlin, потоках, сопрограммах и Jetpack Compose см. на следующих ресурсах:
- Разрабатывайте приложения для Android с помощью Kotlin
- Изучите Kotlin для Android
- Сопрограммы Kotlin на Android . Эти конкретные лаборатории кода могут быть полезны:
- Kotlin работает на Android и, в частности, на StateFlow .
- State и Jetpack Compose , в частности функция
collectAsStateWithLifecycle()
. Эта функция автоматически управляет подпиской и отменой подписки на потоки в зависимости от того, находится ли пользовательский интерфейс, показывающий это состояние, на переднем плане или нет. - Если вы работаете с API автоматизации, чтение о типобезопасных сборщиках Kotlin полезно для понимания того, как работает Automation DSL.