Отваливается — что это, типичные причины и методы решения

Автор: IT Sectr Опубликовано: 2026-07-29 Время чтения: 10 мин

Потеря соединения — одно из самых частых и раздражающих явлений в мобильных приложениях. Пользователь теряет доступ к данным, прерывается операция, приложение зависает или вылетает. По данным Google Android Developer Blog, 70% пользователей удаляют приложение, если оно вылетает или зависает дважды. Разберём причины потери соединения и способы построения отказоустойчивых коммуникаций.

Главное

  • ANR (Application Not Responding) — блокировка UI-потока дольше 5 секунд приводит к принудительному завершению
  • Offline-first — архитектура, где локальное хранилище — источник истины, а сеть — механизм синхронизации
  • Retry with backoff — автоматический повтор запроса с увеличивающейся задержкой при сетевых ошибках
  • ConnectivityManager — Android API для отслеживания состояния сети и адаптации поведения приложения
  • Graceful degradation — приложение должно работать (хотя бы частично) при отсутствии сети

Что значит «отваливается» в мобильных приложениях?

Отваливается — пользовательский термин, описывающий ситуацию, когда приложение теряет соединение с сервером, перестаёт отвечать на действия или завершается с ошибкой. В техническом смысле это может быть: сетевая ошибка (таймаут, DNS failure), ANR (блокировка UI-потока), crash (необработанное исключение) или race condition (состояние гонки).

Для пользователя все эти сценарии выглядят одинаково: приложение перестаёт работать. Разница для разработчика — в подходе к диагностике и исправлению. Сетевые ошибки решаются retry-механизмами, ANR — выносом операций из UI-потока, crash — exception handling.

По данным Crittercism (now Apteligent), в среднем мобильное приложение теряет 1-2% пользователей при каждом падении. Для приложения с 1 млн пользователей это 10-20 тысяч потерянных установок на один баг. Особенно критично для приложений в финансовом и медицинском секторах.

Основные причины потери соединения

Нестабильная сеть — мобильные устройства постоянно переключаются между Wi-Fi и мобильной сетью, заходят в зоны без покрытия (метро, лифт, подвал). Каждое переключение вызывает временную потерю соединения, которую приложение должно обрабатывать корректно.

Таймауты — если сервер не отвечает в течение установленного таймаута (обычно 10-30 секунд), клиент бросает SocketTimeoutException. Долгие таймауты без обратной связи воспринимаются пользователем как зависание. Рекомендуется устанавливать таймаут не более 15 секунд.

kotlin
val client = OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(15, TimeUnit.SECONDS)
    .writeTimeout(15, TimeUnit.SECONDS)
    .retryOnConnectionFailure(true)
    .build()

Состояние гонки (race condition) — возникает, когда несколько потоков одновременно читают и пишут одни и те же данные без синхронизации. Например, загрузка данных из кеша в UI-потоке параллельно с обновлением кеша из сети может привести к отображению устаревших или некорректных данных.

  • Необработанные исключения в callback или корутине приводят к crash приложения
  • Memory pressure — system убивает приложение при нехватке памяти для foreground-приложения
  • Lifecycle race — async операция завершается после того, как Activity/Fragment уничтожен
  • Блокировка UI — выполнение сети или БД на главном потоке вызывает ANR через 5 секунд

Архитектура для отказоустойчивых приложений

Offline-first — архитектурный паттерн, при котором локальное хранилище (Room, CoreData) является единственным источником истины. Сеть используется для синхронизации данных в фоне. Пользователь всегда видит актуальные данные из локального кеша, даже при отсутствии сети.

Repository pattern — единая точка входа для данных, которая решает, брать данные из сети или из кеша. Репозиторий абстрагирует источник данных от ViewModel и UI. При сетевой ошибке репозиторий автоматически переключается на локальный источник.

kotlin
class UserRepository(
    private val api: UserApi,
    private val dao: UserDao
) {
    suspend fun getUsers(): Result<List<User>> {
        return try {
            val remote = api.fetchUsers()
            dao.insertAll(remote)
            Result.success(remote)
        } catch (e: IOException) {
            val cached = dao.getAll()
            if (cached.isNotEmpty()) {
                Result.success(cached) // return cache on network error
            } else {
                Result.failure(e)
            }
        }
    }
}

Circuit Breaker — паттерн защиты сервера от лавины запросов при недоступности. После N последовательных ошибок выключатель размыкается, и все запросы сразу возвращают ошибку без попытки соединения. Через заданный таймаут выключатель переходит в полуоткрытое состояние для пробного запроса.

Как обрабатывать сетевые ошибки?

Exponential backoff — стандартный механизм retry. После первой неудачи подождать 1 секунду, после второй — 2 секунды, затем 4, 8, 16. Ограничьте максимальное количество попыток (обычно 3-5), чтобы не перегружать сервер и батарею.

User feedback — при сетевой ошибке покажите понятное сообщение: «Нет соединения», «Сервер временно недоступен», «Проверьте интернет». Используйте Snackbar или Inline State View. Никогда не показывайте технические ошибки (HTTP 500, SocketException) пользователю.

ConnectivityManager — Android API для мониторинга сети. Разрешите приложение реагировать на изменения: при потере сети показывать placeholder, при восстановлении — автоматически обновлять данные. В iOS используйте NWPathMonitor из Network framework.

kotlin
class NetworkMonitor(private val context: Context) {
    private val manager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    fun isOnline(): Boolean {
        val network = manager.activeNetwork ?: return false
        val caps = manager.getNetworkCapabilities(network) ?: return false
        return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    }
}

Инструменты мониторинга и логирования

Crashlytics (Firebase) — стандартный crash-reporting инструмент для мобильных приложений. Собирает stacktrace всех необработанных исключений, версию ОС, модель устройства и время падения. Позволяет группировать ошибки и назначать ответственных за фиксы.

Sentry — альтернатива Crashlytics с поддержкой performance monitoring. Позволяет трейсить конкретные транзакции (например, «авторизация пользователя») и видеть, на каком шаге произошла ошибка. Performance tracing помогает отличать сетевые таймауты от багов в логике приложения.

Timber — библиотека логирования для Android с автоматическим добавлением тегов по классу. В debug-сборке логгируйте все сетевые запросы и ответы. В release-сборке — только ошибки и предупреждения через Crashlytics.setCustomLog.

ИнструментТипКогда использовать
CrashlyticsCrash reportingВсегда в release — автоматический сбор крашей
SentryCrash + PerformanceКогда нужно профилировать конкретные пользовательские сценарии
TimberLoggingDebug: полное логгирование; Release: только ошибки
HTTP ToolkitNetwork debugЛокальный перехват и анализ HTTP-трафика

По данным Firebase Summit 2023, приложения, внедрившие Crashlytics + Performance Monitoring, сокращают среднее время обнаружения и исправления критических багов с 3 дней до 4 часов. Рекомендуется настроить алерты на каждый crash с частотой >0.1% от активных пользователей.

Часто задаваемые вопросы

Что делать, если приложение вылетает без ошибки?

Если crash не ловится в Crashlytics, проверьте native crash (SIGSEGV, SIGABRT) — они не обрабатываются Java/Kotlin exception handler. В Android это может быть утечка native memory из JNI, в iOS — EXC_BAD_ACCESS. Используйте Breakpad (Android) или PLCrashReporter (iOS) для сбора native crash stacktrace.

Как воспроизвести баг, который проявляется только при плохой сети?

Используйте Network Link Conditioner (встроен в iOS, для Android есть Facebook Network Connection Class или настройки Developer Options > Network > Select network type). Установите задержку 500-3000 ms и потерю пакетов 5-30%. Также можно использовать Charles Proxy или mitmproxy для эмуляции сетевых задержек и разрывов.

Как предотвратить ANR при сетевых запросах?

ANR возникает, если UI-поток заблокирован дольше 5 секунд. Сетевые запросы должны выполняться в фоновом потоке: корутины (viewModelScope.launch(Dispatchers.IO)), RxJava (subscribeOn(Schedulers.io)) или WorkManager для синхронизации. Всегда устанавливайте таймауты на HTTP-клиенте — отсутствие таймаута может привести к вечной блокировке.

Что такое race condition и как его избежать?

Race condition — ситуация, когда результат операции зависит от порядка выполнения потоков. Например, пользователь быстро нажимает кнопку «Отправить» дважды, и запрос уходит дважды. Решение: используйте Mutex, single-threaded executors или state machine (отключите кнопку после первого нажатия). В Kotlin используйте Mutex из корутин или @Synchronized аннотацию.

Как тестировать отказоустойчивость приложения?

Применяйте Chaos Engineering для мобильных приложений: отключайте сеть во время операций, симулируйте высокую задержку, переключайте между Wi-Fi и мобильной сетью, убивайте процесс системой. Инструменты: Facebook Network Connection Class, Charles Proxy, iOS Network Link Conditioner. В CI/CD добавляйте UI-тесты с разными сетевыми условиями через AndroidTest Orchestrator.

Итоги

  • Отваливается — собирательный термин для сетевых ошибок, ANR, crash и race conditions; пользовательский опыт одинаковый, причины разные
  • Сетевые ошибки — самая частая причина; решение включает таймауты (10-15 секунд), exponential backoff и offline-first архитектуру
  • ANR возникает при блокировке UI-потока дольше 5 секунд; сетевые и дисковые операции всегда выполняйте на фоновом потоке
  • Offline-first с Repository pattern: локальное хранилище — источник истины, сеть — механизм синхронизации
  • Crashlytics + Performance Monitoring — минимальный набор для production мониторинга с алертами на частые краши
  • Состояние гонки требует синхронизации потоков: Mutex, State Machine или однопоточный экзекьютор
  • Тестируйте с эмуляцией плохой сети и Chaos Engineering — только так можно выявить проблемы, скрытые в идеальных условиях разработки

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также