Офлайн-режим мобильного приложения: данные и синхронизация

Автономный режим помогает продолжить важную работу, когда сеть пропала или стала нестабильной. Типографика здесь должна быстро объяснить три вещи: какие данные доступны на устройстве, какие изменения ещё не отправлены и что произойдёт после восстановления связи. Разберём, как расставить эти статусы, чтобы не превращать экран в набор тревожных предупреждений.
Офлайн — не один статус
Надпись «Нет интернета» описывает соединение, но не состояние конкретных данных. Каталог может открываться из локальной копии, черновик — сохраняться на устройстве, а новое сообщение — ожидать отправки. Если свести всё к одному красному баннеру, пользователь не поймёт, что именно ограничено и потерялась ли его работа.
Сначала разделите модель на три вопроса:
- Есть ли соединение с сервером сейчас?
- Какие данные можно читать с устройства и насколько они актуальны?
- Какие действия пользователь уже совершил, но сервер ещё не подтвердил?
Один экран может одновременно показывать сохранённый список и отдельный статус неотправленного изменения. Поэтому фраза «вы офлайн» не должна автоматически означать «ничего не работает». Показывайте ограничение только там, где оно влияет на действие.
Для offline-first-приложений Android рекомендует иметь локальный источник данных для важных сценариев чтения; после восстановления связи локальные и сетевые данные могут потребовать согласования. Это архитектурная рекомендация, а не гарантия, что любое приложение умеет редактировать всё без сети. Дизайн должен отражать реальные возможности продукта. Документация Android об offline-first.
Сначала сообщите о состоянии данных
Когда экран открылся без сети, полезнее сразу показать то, что действительно доступно, а затем коротко обозначить ограничение. Например: список проектов остаётся читаемым, рядом с заголовком есть спокойная подпись «Данные на устройстве · обновлены вчера», а кнопка, требующая соединения, сопровождается ясным объяснением.
Иерархию можно выстроить в три уровня:
1. Основной контент — название объекта, сумма, запись или черновик. Он сохраняет обычный размер и контраст: это всё ещё главная задача экрана. 2. Актуальность — короткая метка рядом с данными: «Обновлено 14:20» или «Последняя синхронизация вчера». Её можно набрать стилем вторичной информации, но не делать едва заметной. 3. Доступность действия — подпись возле конкретной команды: «Отправка станет доступна при подключении». Такой текст отвечает на вопрос «почему сейчас нельзя?», не перекрывая весь экран.
Не прячьте давность копии только в общем баннере наверху. Пользователь может открыть сохранённую карточку напрямую, вернуться к ней позже или не заметить сообщение. Метка свежести должна быть связана с данными, срок актуальности которых важен. Для статичной заметки, сохранённой самим пользователем, дата последнего сетевого обновления может быть лишней; для расписания, цены или остатка — существенной.
Покажите, что изменение осталось на устройстве
После редактирования в офлайне главный вопрос обычно не в соединении, а в судьбе ввода. Если действие сохранено локально, скажите это прямо: «Черновик сохранён на устройстве» или «Изменение отправится при подключении». Если сохранение ещё не подтверждено даже локально, не используйте текст «сохранено».
Используйте предсказуемые состояния и короткие формулировки:
- Сохранено локально — пользователь может закрыть экран без потери ввода в рамках заявленных возможностей продукта.
- Ожидает отправки — действие записано, но сервер его ещё не получил.
- Отправляется — синхронизация действительно началась; это временное состояние.
- Подтверждено — сервер принял изменение, и временную офлайн-метку можно убрать.
- Нужно решение — серверные и локальные данные расходятся, требуется выбор или объяснение.
Это не универсальные технические статусы для каждой модели данных. Не показывайте этапы, которые приложение не может надёжно определить. Если можно гарантировать только «сохранено локально», не обещайте, что отправка уже запланирована.
У статуса должна быть понятная типографическая роль: само состояние читается быстро, а подробность — по соседству или после раскрытия. Например, в списке можно показывать небольшую строку «Не отправлено» под названием записи, а во время синхронизации менять её на «Отправляем…». Смысл не должен зависеть лишь от цвета или маленькой пиктограммы.
Разделите общий офлайн-режим и локальное состояние записи
Постоянная плашка во всю ширину экрана быстро становится шумом, особенно когда сеть нестабильна. Используйте общий индикатор, если он помогает объяснить ограничение всего раздела. А состояние конкретного документа, сообщения или задания показывайте возле самого элемента.
Сравните формулировки:
- Неясно: «Ошибка синхронизации».
- Яснее: «Заметка сохранена на устройстве. Отправить её не удалось».
- Ещё полезнее, если это поддерживается: «Заметка сохранена на устройстве. Повторим отправку при подключении».
Избегайте формулировок, которые смешивают наличие сети с успешной записью данных. Полоска «Вы офлайн» не отвечает, сохранился ли черновик. И наоборот: отдельная метка «Не отправлено» понятна даже при наличии связи, если сервер временно недоступен.
Оформите возвращение связи без ложного обещания
Не превращайте появление сигнала сети в сообщение «Всё синхронизировано»: связь восстановилась раньше, чем завершилась передача. Если приложение знает точный этап, покажите короткую последовательность: «Соединение восстановлено» → «Отправляем 2 изменения» → «Синхронизация завершена». Если этапов несколько, достаточно обновлять локальную подпись, не выводя три баннера подряд.
При долгой синхронизации полезна конкретика: «Отправляем 3 файла» или «Обновляем список». Не подставляйте фиктивный процент, если прогресс не измеряется. Для краткой операции отдельный экран загрузки не нужен; состояние можно показать в контексте элемента.
Если данные с сервера изменились за время офлайн-работы, не маскируйте конфликт общей фразой «Ошибка». Назовите объект и следующий шаг: «Пока вы редактировали заметку, появилась более новая версия. Сравните варианты перед сохранением». Когда конфликтов несколько, группируйте их по задаче и не повторяйте одинаковое объяснение под каждой строкой.
Настройте длину и контраст служебных строк
Офлайн-метки часто состоят из коротких слов, поэтому легко сделать их слишком мелкими. Проверьте самый длинный реальный статус, а не только «Офлайн»: «Изменение сохранено локально и будет отправлено при подключении» занимает гораздо больше места. На узком экране текст должен переноситься целиком и оставаться рядом с тем действием, которого касается.
Практические правила:
- Оставляйте основной текст в обычной иерархии, не уменьшайте его из-за служебной плашки.
- Для меток используйте размер, который остаётся читаемым при увеличении системного текста.
- Не передавайте статус только цветом; оставьте слово или короткую фразу.
- Дайте длинной локализованной строке переноситься, а не обрезайте её многоточием.
- Проверьте соседство метки с кнопкой: подпись не должна выглядеть как название самой команды.
- На плотном экране сокращайте формулировку, но не убирайте факт, что данные сохранены локально.
Например, вместо «Ожидает синхронизации» в каждой строке можно использовать «Не отправлено», если контекст списка уже очевиден. Но на отдельном экране без контекста это сокращение может быть недостаточным — там лучше добавить, что именно и куда не отправлено.
Проверьте сценарии до передачи в разработку
Составьте небольшую матрицу состояний для каждого важного действия. Она помогает заметить, что одинаковая строка используется для разных исходов.
Таблица состояний: Сценарий · Что показать рядом с данными · Чего не обещать
- Данные доступны только локально — Последнее подтверждённое обновление — Что копия актуальна сейчас
- Ввод сохранён локально — «Сохранено на устройстве» — Что сервер уже получил изменение
- Изменение ждёт отправки — «Не отправлено» и условие повторной попытки — Что отправка обязательно завершится
- Идёт синхронизация — Что именно обновляется, если это известно — Фиктивный процент готовности
- Найдены конфликтующие версии — Какие данные расходятся и доступный следующий шаг — Что приложение выбрало правильную версию за пользователя
Проверьте таблицу на короткой строке, длинном названии объекта, крупном размере текста, локализации и при нескольких ожидающих изменениях. Если продукт поддерживает редактирование без связи, отдельно проверьте закрытие приложения и повторный запуск: интерфейс должен показывать состояние, которое действительно хранится, а не обещанное по памяти.
Частые ошибки
- Показывать только общий баннер. Он не объясняет, какие записи сохранены и какие действия ограничены. Свяжите статус с контентом или действием.
- Писать «ошибка» вместо результата. Пользователю важнее знать, осталось ли изменение на устройстве и что произойдёт дальше.
- Считать локальное сохранение отправкой. Это разные этапы; называйте тот, который подтверждён.
- Убирать актуальность данных в мелкий серый текст. Давность может влиять на решение пользователя, поэтому метка должна быть заметна в нужном контексте.
- Обещать автоматический повтор без реализации. Формулировка «отправим при подключении» должна соответствовать реальной логике приложения.
- Скрывать конфликт за общим уведомлением. Укажите объект и действие, которое поможет выбрать или согласовать версию.
Контрольный список
- Разделены состояние сети, свежесть данных и очередь изменений.
- Отдельно указано, что сохранено локально и что подтвердил сервер.
- Статус конкретной записи расположен рядом с ней.
- Для каждого действия понятно, что ограничено без связи.
- Возвращение соединения не изображено как завершённая синхронизация.
- Конфликт версий объясняет, что разошлось и как продолжить.
- Длинные строки переносятся, а увеличенный системный текст не перекрывает действия.
- Значение состояния не зависит только от цвета, пиктограммы или анимации.
Частые вопросы
Нужно ли всегда показывать баннер «Нет интернета»?
Нет. Показывайте общее сообщение, если отсутствие сети меняет весь сценарий или важно предупредить о свежести данных. Если ограничена одна запись или команда, привяжите пояснение к ней, чтобы пользователь не воспринимал весь экран как недоступный.
Как назвать данные, которые приложение показывает без сети?
Подберите формулировку под реальный источник и давность: «Данные на устройстве», «Последнее обновление вчера» или «Сохранённая копия». Не называйте их актуальными, если приложение не проверило сервер после получения копии.
Можно ли писать «Сохранено», если сеть отсутствует?
Да, только если приложение надёжно записало изменение локально и продукт обещает сохранить его при закрытии или перезапуске. Чтобы не спутать локальную запись с серверной, лучше сказать «Сохранено на устройстве».
Нужна ли отдельная подпись у каждой неотправленной записи?
Она нужна, если пользователь должен различать, какие именно элементы ещё не переданы. Если список короткий и общий статус точно относится ко всем элементам, можно показать одно сводное сообщение с числом изменений и понятной точкой входа к ним.
Как оформить конфликт двух версий?
Назовите объект, укажите, что есть более новая или параллельная версия, и предложите понятный следующий шаг. Не сводите выбор к цветным меткам и не перезаписывайте данные молча, если от выбора зависит работа пользователя.
Должен ли статус синхронизации мигать или анимироваться?
Нет, анимация не заменяет ясную подпись. Используйте её только для реально происходящей операции, не делайте движение единственным сигналом и не оставляйте «отправляется» после завершения процесса.
Как проверить эти строки перед выпуском?
Соберите реальные статусы рядом с данными и командами, проверьте их на узком экране, увеличенном тексте и локализациях. Затем пройдите офлайн-сценарий до повторного подключения и сверьте каждое обещание интерфейса с фактическим состоянием данных.
Итог
Хорошая типографика автономного режима отделяет содержимое от служебного статуса, но не делает статус незаметным. Пользователь должен отличать локальную копию, сохранённое изменение, отправку и конфликт. Если вы создаёте собственный рукописный шрифт для интерфейса, проверьте читаемость кириллицы и цифр в Fontgenerator на реальных коротких и длинных метках.
Источник по архитектуре: Build an offline-first app — Android Developers.