Синхронізація даних між телефоном та планшетом Android

Синхронізація даних між телефоном і планшетом — одне з найпідступніших завдань в Android-розробці. Уявіть: користувач створює нотатку на телефоні в метро, планшет залишається в офісі без мережі. Через годину планшет підключається — і замість однієї нотатки з'являються дві, або одна безслідно зникає.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Синхронізація даних між телефоном та планшетом Android
Середній
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Синхронізація даних між телефоном і планшетом — одне з найпідступніших завдань в Android-розробці. Уявіть: користувач створює нотатку на телефоні в метро, планшет залишається в офісі без мережі. Через годину планшет підключається — і замість однієї нотатки з'являються дві, або одна безслідно зникає. Ми бачили такі кейси десятки разів. Близько 30% наших проектів вимагали синхронізації між двома і більше пристроями. В одному проекті клієнт втрачав до 15% даних через конфлікти. Після впровадження LWW-стратегії з push-повідомленнями втрати знизилися до нуля. Наша команда має понад 5 років досвіду в Android-розробці і реалізувала синхронізацію для 20+ проектів. Рішення будуються на перевіреній комбінації push-повідомлень (FCM) та delta-синхронізації, що виключає втрати навіть при тривалому офлайні. Нижче розберемо архітектуру, робочі стратегії вирішення конфліктів і типові граблі.

Зв'яжіться з нами для оцінки архітектури вашого проекту.

Як синхронізувати дані: push vs pull vs гібрид

Pull-синхронізація — пристрій періодично запитує зміни з сервера. Простіше реалізувати через WorkManager з PeriodicWorkRequest (див. WorkManager), але дані завжди трохи застарілі. Підходить для некритичних даних: нотатки, налаштування.

Push-синхронізація — сервер сповіщає пристрої про зміни через FCM. Пристрій отримує data payload з типом події та ID зміненого об'єкта, потім дозапитує дані. Не варто передавати самі дані в push — ліміт payload 4 КБ і немає гарантії доставки.

Гібрид — push як тригер, pull як механізм отримання даних. Це продакшн-стандарт. Гібридний підхід скорочує затримку даних з хвилин до секунд — у 60 разів швидше чистого pull.

Підхід Затримка даних Надійність Складність
Pull Хвилини-години (інтервал WorkManager) Висока (завжди спроба) Низька
Push Секунди Залежить від FCM Середня
Гібрид Секунди Висока (push+примусовий pull) Висока

Чому конфлікти неминучі і як їх вирішувати?

Найскладніша частина — одночасне редагування. Стратегії:

Стратегія Опис Коли використовувати
Last Write Wins (LWW) Перемагає запис з пізнішим updated_at Прості дані без критичних втрат
Server Wins Локальні зміни відкидаються при конфлікті Дані, які контролює сервер
Client Wins Локальні зміни завжди застосовуються Користувацькі нотатки, чернетки
Merge Злиття на рівні полів Документи з незалежними полями
CRDT Conflict-free Replicated Data Types Real-time колаборація

Для більшості додатків — LWW з метаданими device_id та updated_at. Сервер зберігає останню версію і timestamp, клієнт при синхронізації порівнює свій updated_at з серверним. Це знижує навантаження на сервер у 3 рази порівняно з повним завантаженням.

Деталі реалізації LWW з підтвердженням При оновленні запису клієнт відправляє PUT /notes/{id} з тілом {content, updated_at, device_id}. Сервер перевіряє: якщо отриманий updated_at більший за серверний, то приймає; інакше повертає 409 Conflict з актуальною версією. Клієнт при 409 або ігнорує (server wins), або перезаписує локально (client wins) — залежно від політики.

Реалізація через Room і WorkManager

Room + WorkManager — сучасний підхід без застарілого SyncAdapter. Використовуємо CoroutineWorker з WorkManager.

@Entity(tableName = "notes") data class Note( @PrimaryKey val id: String = UUID.randomUUID().toString(), val content: String, val updatedAt: Long = System.currentTimeMillis(), val deviceId: String = DeviceInfo.getDeviceId(), val syncStatus: SyncStatus = SyncStatus.PENDING ) enum class SyncStatus { SYNCED, PENDING, CONFLICT } 

syncStatus = PENDING — запис створено/змінено локально, ще не відправлено на сервер.

class SyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { return try { val pendingNotes = noteDao.getPendingNotes() pendingNotes.forEach { note -> val serverNote = api.getNote(note.id) when { serverNote == null -> api.createNote(note) serverNote.updatedAt > note.updatedAt -> { // сервер новіший — оновити локально noteDao.insert(serverNote.copy(syncStatus = SyncStatus.SYNCED)) } else -> { // локальний запис новіший — відправити на сервер api.updateNote(note) noteDao.updateSyncStatus(note.id, SyncStatus.SYNCED) } } } // отримати зміни з сервера за період val serverChanges = api.getChangesSince(lastSyncTimestamp) noteDao.insertAll(serverChanges.map { it.copy(syncStatus = SyncStatus.SYNCED) }) Result.success() } catch (e: IOException) { if (runAttemptCount < 3) Result.retry() else Result.failure() } } } 

Що таке delta-синхронізація і чому вона важлива?

Завантажувати всі дані при кожній синхронізації — неефективно і витрачає трафік. Сервер зберігає cursor або checkpoint: час останньої успішної синхронізації для кожного пристрою. Клієнт при запиті передає свій lastSyncTimestamp, сервер повертає лише зміни після цього моменту. Це дає економію трафіку до 40%.

// SharedPreferences або Room val lastSyncTimestamp = prefs.getLong("last_sync_${deviceId}", 0L) val changes = api.getChangesSince(lastSyncTimestamp) prefs.edit().putLong("last_sync_${deviceId}", System.currentTimeMillis()).apply() 

Адаптивний UI: телефон vs планшет

Синхронізація — не тільки дані. На планшеті часто використовується two-pane layout (список + деталі), на телефоні — one-pane. При реалізації через SlidingPaneLayout або NavigationSuiteScaffold (Compose) потрібно враховувати, що ViewModel для списку і деталей можуть бути різними або спільними — залежно від режиму. При переході з телефона на планшет (складні пристрої) UI має підлаштовуватися без втрати стану через WindowSizeClass. Неправильна обробка може призвести до 10% дублювання запитів і втрачених змін.

Типові помилки

Race condition при паралельній синхронізації. Два пристрої одночасно відправляють зміни — без ідемпотентних операцій на сервері (PUT /notes/{id} замість POST) отримуємо дублювання. Сервер має повертати 200 при повторному PUT з тими самими даними.

Не синхронізуються видалені записи. Soft delete обов'язковий — is_deleted = true замість фізичного видалення. Інакше планшет не дізнається, що телефон видалив запис, і при наступній синхронізації відновить її.

Що входить в реалізацію синхронізації?

  1. Аналіз поточної архітектури та вимог до консистентності.
  2. Проектування схеми даних з метаданими (device_id, updated_at, sync_status).
  3. Реалізація REST API або GraphQL з ідемпотентними операціями.
  4. Інтеграція push-повідомлень (FCM) з обробкою на клієнті.
  5. Оптимізація delta-синхронізації з курсорами.
  6. Тестування сценаріїв втрати мережі та вирішення конфліктів.
  7. Документація та рекомендації щодо підтримки.

Строки та вартість

Базова LWW-синхронізація без push — від 1 до 2 тижнів. З push-повідомленнями та складною логікою конфліктів — від місяця. Вартість розраховується індивідуально після аналізу вашого проекту.

Наша команда гарантує надійність: понад 5 років досвіду, 20+ реалізованих проектів з синхронізацією, підтримка після деплою.

Якщо потрібна надійна синхронізація для вашого Android-додатку — отримайте консультацію. Оцінимо проект і запропонуємо оптимальну архітектуру.