Remote Compose – это библиотека Jetpack, которая позволяет создавать пользовательский интерфейс с помощью API в стиле Compose в приложении и отображать его в системных процессах, таких как виджеты приложений или виджеты Wear OS. Приложение записывает интерфейс в виде компактного документа, а проигрыватель в хост-процессе отрисовывает его и обрабатывает взаимодействия, изменения состояния и анимацию локально, не обращаясь к приложению.
В этом руководстве рассказывается об архитектуре Remote Compose и о том, чем она отличается от стандартной архитектуры Jetpack Compose. В этом руководстве рассказывается о создании интерфейса с помощью компонентов.
Примеры использования удаленного создания
Remote Compose можно использовать на любой платформе с поддерживаемым проигрывателем. На Android он используется для виджетов приложений и виджетов Wear OS.
Как это работает: архитектура из трех блоков
Основное архитектурное различие между Remote Compose и стандартным Jetpack Compose заключается в разделении определения пользовательского интерфейса и его выполнения на три высокоуровневых блока:
- Создание документа. Приложение запускает функции
@RemoteComposable, чтобы записать документ – компактное сериализованное описание интерфейса, включая его макет, удаленное состояние и действия. Когда данные меняются, приложение может записать и отправить новый документ. - Передача документа на удаленный хост. Приложение передает документ хосту, который его показывает, например лаунчеру или Wear OS.
- Воспроизведение документа. Проигрыватель Remote Compose на хосте отрисовывает документ и локально обрабатывает макет, ввод, изменения состояния UX и анимацию, не обращаясь к вашему приложению.
Такая архитектура обеспечивает основные преимущества, которые напрямую снижают задержку:
- Небольшой размер документа. Сериализованные снимки документов остаются компактными и легкими.
- Меньше циклов обмена данными. Поскольку удаленный проигрыватель обрабатывает взаимодействия и изменения состояния локально, циклы обмена данными с приложением или сервером сведены к минимуму.
Аналогия с веб-страницей и HTML. Удаленное создание работает так же, как показ веб-страницы. Сервер приложения генерирует и отправляет структуру HTML/документа один раз, а хост браузера отрисовывает ее и обрабатывает взаимодействия локально, не отправляя постоянно запросы к серверной части.
Компоненты
Remote Compose предоставляет высокоуровневые компоненты пользовательского интерфейса для структурирования макетов. Используйте компоненты Remote Compose и RemoteModifier вместо их стандартных эквивалентов Compose. К ним относятся базовые контейнеры макетов, а также адаптивные компоненты, специально разработанные для работы с динамическими размерами экрана:
- Основные компоненты макета. Стандартные элементы макета, похожие на Compose, такие как
RemoteBox,RemoteRowиRemoteColumn. - Компоненты адаптивного макета. Специализированные компоненты, такие как
RemoteFitBox,RemoteCollapsibleRowиRemoteCollapsibleColumn, предназначенные для адаптации к удаленным поверхностям. - Темы Material Design. Темы работают для виджетов Wear OS так же, как и для других, с иерархией цветов и типографики, предоставляемой
RemoteMaterialTheme. Это позволяет обеспечить единообразие брендинга и дизайна в приложении и виджетах.
Специальный рисунок с RemoteCanvas
Для пользовательской графики и анимации на основе времени используйте RemoteCanvas, который записывает команды рисования, выполняемые проигрывателем на хосте. В этом руководстве рассказывается о том, как создавать интерфейс с помощью компонентов.
Основные различия
Review the following core concepts to understand how Remote Compose manages state, logic, and actions.
Символические ссылки на состояния
В стандартном Compose контейнеры состояний содержат активные, доступные для чтения значения в локальной памяти приложения, которые изменяются кодом приложения (лямбда-выражениями) при возникновении событий. В Remote Compose объявления состояний действуют как символические ссылки. Вместо того чтобы хранить активные значения в локальной памяти приложения, они объявляют привязки, которыми удаленный проигрыватель управляет и которые обновляет локально во время выполнения. При объявлении состояния в Remote Compose учитывайте следующее:
- Используйте фабричные функции Remote Compose, чтобы объявить состояние, например
rememberMutableRemoteInt,rememberMutableRemoteFloatилиrememberMutableRemoteString. - Код приложения не может проверять или считывать значение переменной удаленного состояния непосредственно во время компоновки.
- Проигрыватель сохраняет и обновляет эти значения локально по мере того, как пользователь взаимодействует с документом.
Удаленное состояние и поток управления Kotlin
Код Kotlin выполняется только при создании документа приложением. Операторы Kotlin, такие как if, when и for, могут формировать документ на основе значений, известных в данный момент, например повторять строку для каждого элемента в списке, но они не могут реагировать на удаленное состояние, которое изменится позже. При работе с удаленным редактором учитывайте следующее:
- Логика ветвления. Динамическое переключение интерфейса выполняется с помощью
RemoteStateLayoutпутем сопоставления состояния с разными слотамиRemoteComposable. - Оценка текста. Избегайте стандартной интерполяции строк Kotlin (
$remoteValue), которая оценивается только при создании документа. Вместо этого передайтеRemoteStringвRemoteText.
Динамическое оформление с помощью RemoteModifier
Динамическое оформление на хосте не запускает компоновку повторно. Вместо этого переменные удаленного состояния передаются напрямую в модификаторы, такие как RemoteModifier.background(remoteColor).
Контекст удаленной системы
CompositionLocal, такие как LocalConfiguration или LocalDensity, отражают только локальную среду приложения в момент записи документа. Они не обновляются динамически на удаленном хосте при изменении размера поверхности, состояния дисплея или времени. Вместо этого используйте значения, которые проигрыватель определяет на хосте во время выполнения, например текущий размер компонента, RemoteConfiguration или RemoteDensity.
Декларативные действия
В стандартном Compose обработчики кликов – это лямбда-выражения, которые выполняются в приложении. Хост не может запустить код приложения, поэтому в Remote Compose вместо этого вы прикрепляете действия, например с помощью RemoteModifier.clickable(action). Действие может напрямую обновлять удаленное состояние на хосте с помощью valueChange или передавать его вашему приложению или хосту с помощью pendingIntentAction или hostAction. Чтобы выполнить несколько действий одним кликом, используйте combinedAction.
Сравнение парадигм высокого уровня
Домен функции |
Стандартный Jetpack Compose |
Удаленное создание |
|---|---|---|
События кликов и касаний |
Синхронные лямбда-выражения в процессе |
Декларативные сериализованные объекты Action |
Условная логика |
Управляющие конструкции if и when в Kotlin |
Стандартный Kotlin Для динамического ветвления используется |
Циклы управления потоком |
Стандартные циклы for и while в Kotlin |
Стандартные циклы Kotlin (repeat, for, forEach) выполняются только при создании документа. Они не могут зацикливаться на удаленном состоянии на хосте. |
Хост выполнения |
Процесс приложения |
Лаунчер (AppWidget), виджеты Wear OS или любой другой тип устройства с поддерживаемым проигрывателем. |
Жизненный цикл процесса |
Для рекомпозиции и рендеринга процесс должен оставаться активным. |
Обрабатывает документ со снимком интерфейса. Движок Remote Player анализирует дерево компонентов, отслеживает изменения состояния и перерисовывает интерфейс локально, не обращаясь к приложению. |
Побочные эффекты |
Жизненные циклы сопрограмм (LaunchedEffect) |
Недоступно на хосте. Композиция запускается в вашем приложении для создания документа, поэтому эффекты сопрограммы не могут управлять удаленным пользовательским интерфейсом, если только интеграция не поддерживает композицию открытой. |
Парадигма состояния |
Значения состояния локальной памяти |
Фабричные функции (rememberMutableRemoteInt(), rememberNamedRemoteColor()), которые возвращают символические ссылки на состояние, а не необработанные значения. |