Perdita di connessione — cause tipiche e metodi di soluzione

Autore: IT Sectr Pubblicato: 2026-07-29 Tempo di lettura: 10 min

Perdita di connessione — uno dei fenomeni più comuni e frustranti nelle applicazioni mobili. L’utente perde l’accesso ai dati, un’operazione viene interrotta, l’app si blocca o si arresta. Secondo Google Android Developer Blog, il 70% degli utenti elimina un’app se si blocca o si arresta due volte. Analizziamo le cause della perdita di connessione e i modi per costruire comunicazioni tolleranti ai guasti.

Punti chiave

  • ANR (Application Not Responding) — il blocco del thread UI per più di 5 secondi porta alla terminazione forzata
  • Offline-first — architettura in cui l’archiviazione locale è la fonte della verità e la rete è un meccanismo di sincronizzazione
  • Retry with backoff — tentativo automatico di richiesta con ritardo crescente in caso di errori di rete
  • ConnectivityManager — API Android per monitorare lo stato della rete e adattare il comportamento dell’app
  • Graceful degradation — l’app dovrebbe funzionare (almeno parzialmente) senza connessione di rete

Cosa significa “perdita di connessione” nelle app mobili?

Perdita di connessione — termine utente che descrive una situazione in cui l’app perde la connessione al server, smette di rispondere alle azioni o termina con un errore. In termini tecnici, può essere: errore di rete (timeout, fallimento DNS), ANR (congelamento del thread UI), crash (eccezione non gestita) o condizione di gara (race condition).

Dal punto di vista dell’utente, tutti questi scenari sembrano uguali: l’app smette di funzionare. La differenza per gli sviluppatori sta nell’approccio di diagnosi e correzione. Gli errori di rete si risolvono con meccanismi di tentativo, l’ANR spostando le operazioni dal thread UI, i crash con la gestione delle eccezioni.

Secondo Crittercism (ora Apteligent), in media un’app mobile perde l’1–2% degli utenti a ogni crash. Per un’app con 1 milione di utenti, ciò significa 10–20 mila installazioni perse per un singolo bug. Questo è particolarmente critico per le app nei settori finanziario e medico.

Cause principali della perdita di connessione

Rete instabile — i dispositivi mobili passano continuamente tra Wi-Fi e rete cellulare, entrando in aree senza copertura (metrò, ascensore, seminterrato). Ogni passaggio causa una perdita temporanea di connessione che l’app deve gestire correttamente.

Timeout — se il server non risponde entro il timeout impostato (di solito 10–30 secondi), il client lancia SocketTimeoutException. I timeout lunghi senza feedback vengono percepiti dall’utente come un blocco. Si consiglia di impostare un timeout non superiore a 15 secondi.

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

Condizione di gara (race condition) — si verifica quando più thread leggono e scrivono gli stessi dati contemporaneamente senza sincronizzazione. Ad esempio, caricare dati dalla cache nel thread UI mentre si aggiorna la cache dalla rete può portare alla visualizzazione di dati obsoleti o errati.

  • Eccezioni non gestite in un callback o coroutine portano al crash dell’app
  • Pressione di memoria — il sistema uccide l’app quando non c’è memoria sufficiente per l’app in primo piano
  • Gara del ciclo di vita — un’operazione asincrona viene completata dopo che Activity/Fragment è stato distrutto
  • Blocco UI — eseguire operazioni di rete o database sul thread principale causa ANR dopo 5 secondi

Architettura per applicazioni tolleranti ai guasti

Offline-first — un modello architetturale in cui l’archiviazione locale (Room, CoreData) è l’unica fonte della verità. La rete viene utilizzata per la sincronizzazione dei dati in background. L’utente vede sempre dati aggiornati dalla cache locale, anche senza connessione di rete.

Modello Repository — un punto di ingresso unico per i dati che decide se ottenere i dati dalla rete o dalla cache. Il repository astrae la fonte dati dal ViewModel e dall’UI. In caso di errore di rete, il repository passa automaticamente alla fonte locale.

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 — un modello che protegge il server da un’ondata di richieste quando non è disponibile. Dopo N errori consecutivi, l’interruttore si apre e tutte le richieste restituiscono immediatamente un errore senza tentare la connessione. Dopo un determinato timeout, l’interruttore passa a uno stato semiaperto per una richiesta di prova.

Come gestire gli errori di rete?

Backoff esponenziale — un meccanismo di tentativo standard. Dopo il primo fallimento, attendere 1 secondo; dopo il secondo, 2 secondi; poi 4, 8, 16. Limitare il numero massimo di tentativi (di solito 3–5) per non sovraccaricare il server e la batteria.

Feedback all’utente — in caso di errore di rete, mostrare un messaggio chiaro: “Nessuna connessione”, “Server temporaneamente non disponibile”, “Controlla la tua connessione Internet”. Utilizzare Snackbar o Inline State View. Mai mostrare errori tecnici (HTTP 500, SocketException) all’utente.

ConnectivityManager — API Android per il monitoraggio della rete. Consentire all’app di reagire ai cambiamenti: mostrare un segnaposto in caso di perdita di connessione, aggiornare automaticamente i dati al ripristino. Su iOS utilizzare NWPathMonitor dal 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)
    }
}

Strumenti di monitoraggio e registrazione

Crashlytics (Firebase) — uno strumento standard di segnalazione crash per app mobili. Raccoglie stacktrace di tutte le eccezioni non gestite, versione del SO, modello del dispositivo e ora del crash. Permette di raggruppare errori e assegnare responsabili per le correzioni.

Sentry — un’alternativa a Crashlytics con supporto per il monitoraggio delle prestazioni. Permette di tracciare transazioni specifiche (ad esempio, “authorizzazione utente”) e vedere in quale fase si è verificato un errore. Il tracing delle prestazioni aiuta a distinguere i timeout di rete dai bug nella logica dell’app.

Timber — una libreria di registrazione per Android con aggiunta automatica di tag per classe. Nelle build di debug, registra tutte le richieste e risposte di rete. Nelle build di release, registra solo errori e avvisi tramite Crashlytics.setCustomLog.

StrumentoTipoQuando usarlo
CrashlyticsSegnalazione crashSempre in release — raccolta automatica crash
SentryCrash + PrestazioniQuando è necessario profilare scenari utente specifici
TimberRegistrazioneDebug: registrazione completa; Release: solo errori
HTTP ToolkitDebug di reteIntercettazione e analisi locale del traffico HTTP

Secondo Firebase Summit 2023, le app che hanno implementato Crashlytics + Performance Monitoring riducono il tempo medio di rilevamento e correzione dei bug critici da 3 giorni a 4 ore. Si consiglia di impostare avvisi per ogni crash con una frequenza superiore allo 0,1% degli utenti attivi.

Domande frequenti

Cosa fare se l’app si blocca senza errore?

Se un crash non viene rilevato in Crashlytics, controlla i crash nativi (SIGSEGV, SIGABRT) — non vengono gestiti dal gestore di eccezioni Java/Kotlin. In Android, potrebbe essere una perdita di memoria nativa da JNI; in iOS, EXC_BAD_ACCESS. Utilizza Breakpad (Android) o PLCrashReporter (iOS) per raccogliere stacktrace di crash nativi.

Come riprodurre un bug che si manifesta solo con rete scarsa?

Utilizza Network Link Conditioner (integrato in iOS; per Android, usa Facebook Network Connection Class o Developer Options > Network > Select network type). Imposta un ritardo di 500–3000 ms e una perdita di pacchetti del 5–30%. Puoi anche utilizzare Charles Proxy o mitmproxy per simulare latenza di rete e disconnessioni.

Come prevenire ANR durante le richieste di rete?

ANR si verifica se il thread UI è bloccato per più di 5 secondi. Le richieste di rete dovrebbero essere eseguite in un thread in background: coroutine (viewModelScope.launch(Dispatchers.IO)), RxJava (subscribeOn(Schedulers.io)), o WorkManager per la sincronizzazione. Imposta sempre timeout sul client HTTP — l’assenza di timeout può portare a un blocco permanente.

Cos’è una condizione di gara e come evitarla?

Condizione di gara — una situazione in cui il risultato di un’operazione dipende dall’ordine di esecuzione dei thread. Ad esempio, un utente preme rapidamente due volte il pulsante “Invia” e la richiesta viene inviata due volte. Soluzione: utilizza Mutex, executor a thread singolo o una macchina a stati (disabilita il pulsante dopo il primo clic). In Kotlin, utilizza Mutex dalle coroutine o l’annotazione @Synchronized.

Come testare la tolleranza ai guasti dell’applicazione?

Applica Chaos Engineering per le app mobili: disconnetti la rete durante le operazioni, simula alta latenza, passa tra Wi-Fi e rete cellulare, uccidi il processo tramite il sistema. Strumenti: Facebook Network Connection Class, Charles Proxy, iOS Network Link Conditioner. In CI/CD, aggiungi test UI con diverse condizioni di rete tramite AndroidTest Orchestrator.

Riepilogo

  • Perdita di connessione — termine collettivo per errori di rete, ANR, crash e condizioni di gara; l’esperienza utente è la stessa, ma le cause differiscono
  • Errori di rete — la causa più comune; le soluzioni includono timeout (10–15 secondi), backoff esponenziale e architettura offline-first
  • ANR si verifica quando il thread UI è bloccato per più di 5 secondi; esegui sempre operazioni di rete e disco in un thread in background
  • Offline-first con modello Repository: l’archiviazione locale è la fonte della verità, la rete è un meccanismo di sincronizzazione
  • Crashlytics + Performance Monitoring — il set minimo per il monitoraggio in produzione con avvisi sui crash frequenti
  • Condizioni di gara richiedono sincronizzazione dei thread: Mutex, macchina a stati o executor a thread singolo
  • Testa con simulazione di rete scarsa e Chaos Engineering — solo così si possono scoprire problemi nascosti in condizioni di sviluppo ideali

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche