Perda de conexão — causas típicas e métodos de solução

Autor: IT Sectr Publicado: 2026-07-29 Tempo de leitura: 10 min

Perda de conexão — um dos fenômenos mais comuns e frustrantes em aplicações móveis. O usuário perde acesso aos dados, uma operação é interrompida, o aplicativo congela ou fecha. De acordo com o Google Android Developer Blog, 70% dos usuários deletam um aplicativo se ele fecha ou congela duas vezes. Vamos analisar as causas da perda de conexão e formas de construir comunicações tolerantes a falhas.

Pontos principais

  • ANR (Application Not Responding) — bloqueio da thread de UI por mais de 5 segundos leva ao encerramento forçado
  • Offline-first — arquitetura onde o armazenamento local é a fonte da verdade e a rede é um mecanismo de sincronização
  • Retry with backoff — repetição automática de requisição com atraso crescente em erros de rede
  • ConnectivityManager — API Android para monitorar o estado da rede e adaptar o comportamento do aplicativo
  • Graceful degradation — o aplicativo deve funcionar (pelo menos parcialmente) sem conexão de rede

O que significa “perda de conexão” em aplicativos móveis?

Perda de conexão — termo do usuário que descreve uma situação em que o aplicativo perde a conexão com o servidor, para de responder a ações ou termina com um erro. Em termos técnicos, isso pode ser: erro de rede (timeout, falha de DNS), ANR (congelamento da thread de UI), crash (exceção não tratada) ou condição de corrida (race condition).

Da perspectiva do usuário, todos esses cenários parecem iguais: o aplicativo para de funcionar. A diferença para os desenvolvedores está na abordagem de diagnóstico e correção. Erros de rede são resolvidos com mecanismos de repetição, ANR removendo operações da thread de UI, crashes com tratamento de exceções.

De acordo com a Crittercism (agora Apteligent), em média um aplicativo móvel perde 1–2% dos usuários a cada crash. Para um aplicativo com 1 milhão de usuários, isso significa 10–20 mil instalações perdidas por um único bug. Isso é especialmente crítico para aplicativos nos setores financeiro e médico.

Principais causas de perda de conexão

Rede instável — dispositivos móveis alternam constantemente entre Wi-Fi e rede celular, entrando em áreas sem cobertura (metrô, elevador, subsolo). Cada alternância causa uma perda temporária de conexão que o aplicativo deve tratar corretamente.

Timeouts — se o servidor não responder dentro do timeout definido (geralmente 10–30 segundos), o cliente lança SocketTimeoutException. Timeouts longos sem feedback são percebidos pelo usuário como congelamento. Recomenda-se definir um timeout de no máximo 15 segundos.

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

Condição de corrida (race condition) — ocorre quando várias threads leem e escrevem os mesmos dados simultaneamente sem sincronização. Por exemplo, carregar dados do cache na thread de UI enquanto atualiza o cache da rede pode levar à exibição de dados desatualizados ou incorretos.

  • Exceções não tratadas em um callback ou corrotina levam a crashes do aplicativo
  • Pressão de memória — o sistema mata o aplicativo quando não há memória suficiente para o aplicativo em primeiro plano
  • Corrida de ciclo de vida — uma operação assíncrona é concluída após a Activity/Fragment ter sido destruída
  • Bloqueio de UI — executar operações de rede ou banco de dados na thread principal causa ANR após 5 segundos

Arquitetura para aplicações tolerantes a falhas

Offline-first — um padrão arquitetural onde o armazenamento local (Room, CoreData) é a única fonte da verdade. A rede é usada para sincronização de dados em segundo plano. O usuário sempre vê dados atualizados do cache local, mesmo sem conexão de rede.

Padrão Repository — um ponto de entrada único para dados que decide se busca dados da rede ou do cache. O repository abstrai a fonte de dados do ViewModel e da UI. Em caso de erro de rede, o repository muda automaticamente para a fonte local.

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 — um padrão que protege o servidor de uma avalanche de requisições quando está indisponível. Após N erros consecutivos, o disjuntor abre, e todas as requisições retornam imediatamente um erro sem tentar conexão. Após um timeout determinado, o disjuntor transita para um estado semiaberto para uma requisição de teste.

Como lidar com erros de rede?

Exponential backoff — um mecanismo de repetição padrão. Após a primeira falha, aguarde 1 segundo; após a segunda, 2 segundos; depois 4, 8, 16. Limite o número máximo de tentativas (geralmente 3–5) para não sobrecarregar o servidor e a bateria.

Feedback ao usuário — em caso de erro de rede, mostre uma mensagem clara: “Sem conexão”, “Servidor temporariamente indisponível”, “Verifique sua internet”. Use Snackbar ou Inline State View. Nunca mostre erros técnicos (HTTP 500, SocketException) ao usuário.

ConnectivityManager — API Android para monitoramento de rede. Permita que o aplicativo reaja a mudanças: mostre um placeholder ao perder conexão, atualize automaticamente os dados ao restaurar. No iOS use NWPathMonitor do framework Network.

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)
    }
}

Ferramentas de monitoramento e registro

Crashlytics (Firebase) — uma ferramenta padrão de relatório de crashes para aplicativos móveis. Coleta stacktraces de todas as exceções não tratadas, versão do SO, modelo do dispositivo e hora do crash. Permite agrupar erros e atribuir responsáveis por correções.

Sentry — uma alternativa ao Crashlytics com suporte a monitoramento de desempenho. Permite rastrear transações específicas (por exemplo, “authorização do usuário”) e ver em qual etapa ocorreu um erro. Performance tracing ajuda a distinguir timeouts de rede de bugs na lógica do aplicativo.

Timber — uma biblioteca de registro para Android com adição automática de tags por classe. Em builds de depuração, registre todas as requisições e respostas de rede. Em builds de lançamento, registre apenas erros e avisos via Crashlytics.setCustomLog.

FerramentaTipoQuando usar
CrashlyticsRelatório de crashesSempre em release — coleta automática de crashes
SentryCrash + DesempenhoQuando precisar perfilar cenários de usuário específicos
TimberRegistroDebug: registro completo; Release: apenas erros
HTTP ToolkitDepuração de redeInterceptação e análise local de tráfego HTTP

De acordo com o Firebase Summit 2023, aplicativos que implementaram Crashlytics + Performance Monitoring reduzem o tempo médio de detecção e correção de bugs críticos de 3 dias para 4 horas. Recomenda-se configurar alertas para cada crash com frequência acima de 0.1% dos usuários ativos.

Perguntas frequentes

O que fazer se o aplicativo fechar sem erro?

Se um crash não for detectado no Crashlytics, verifique crashes nativos (SIGSEGV, SIGABRT) — eles não são tratados pelo manipulador de exceções Java/Kotlin. No Android, isso pode ser vazamento de memória nativa do JNI; no iOS, EXC_BAD_ACCESS. Use Breakpad (Android) ou PLCrashReporter (iOS) para coletar stacktraces de crashes nativos.

Como reproduzir um bug que só se manifesta em rede ruim?

Use o Network Link Conditioner (integrado no iOS; para Android, use Facebook Network Connection Class ou Developer Options > Network > Select network type). Defina um atraso de 500–3000 ms e perda de pacotes de 5–30%. Você também pode usar Charles Proxy ou mitmproxy para simular latência e desconexões de rede.

Como prevenir ANR durante requisições de rede?

ANR ocorre se a thread de UI estiver bloqueada por mais de 5 segundos. Requisições de rede devem ser executadas em uma thread em segundo plano: corrotinas (viewModelScope.launch(Dispatchers.IO)), RxJava (subscribeOn(Schedulers.io)), ou WorkManager para sincronização. Sempre defina timeouts no cliente HTTP — a falta de timeout pode levar a um bloqueio permanente.

O que é uma condição de corrida e como evitá-la?

Condição de corrida — uma situação em que o resultado de uma operação depende da ordem de execução das threads. Por exemplo, um usuário pressiona rapidamente o botão “Enviar” duas vezes, e a requisição é enviada duas vezes. Solução: use Mutex, executores de thread única ou uma máquina de estados (desative o botão após o primeiro clique). Em Kotlin, use Mutex de corrotinas ou a anotação @Synchronized.

Como testar a tolerância a falhas do aplicativo?

Aplique Chaos Engineering para aplicativos móveis: desconecte a rede durante operações, simule alta latência, alterne entre Wi-Fi e rede celular, mate o processo pelo sistema. Ferramentas: Facebook Network Connection Class, Charles Proxy, iOS Network Link Conditioner. Em CI/CD, adicione testes de UI com diferentes condições de rede via AndroidTest Orchestrator.

Resumo

  • Perda de conexão — termo coletivo para erros de rede, ANR, crashes e condições de corrida; a experiência do usuário é a mesma, mas as causas diferem
  • Erros de rede — a causa mais comum; soluções incluem timeouts (10–15 segundos), exponential backoff e arquitetura offline-first
  • ANR ocorre quando a thread de UI está bloqueada por mais de 5 segundos; sempre execute operações de rede e disco em uma thread em segundo plano
  • Offline-first com padrão Repository: armazenamento local é a fonte da verdade, a rede é um mecanismo de sincronização
  • Crashlytics + Performance Monitoring — o conjunto mínimo para monitoramento em produção com alertas sobre crashes frequentes
  • Condições de corrida exigem sincronização de threads: Mutex, Máquina de Estados ou executor de thread única
  • Teste com simulação de rede ruim e Chaos Engineering — só assim é possível descobrir problemas ocultos em condições ideais de desenvolvimento

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também