Come funziona l'installazione delle app Android dietro le quinte

A smartphone on engineering blueprints with gears, illustrating how app installation works

Quando tocchi "Installa" su un file APK o scarichi un'app dal Play Store, dietro le quinte inizia una complessa sequenza di operazioni. Quella che sembra essere una semplice barra di avanzamento rappresenta in realtà decine di passaggi che coinvolgono l'analisi dei pacchetti, la verifica crittografica, la gestione dei permessi, l'estrazione dei file e l'ottimizzazione del codice. Comprendere questo processo aiuta a spiegare perché le installazioni a volte falliscono e cosa puoi fare al riguardo.

In questo articolo esamineremo tutti i passaggi principali della pipeline di installazione di Android, dal momento in cui il sistema riceve un APK fino al punto in cui l'app è pronta per l'avvio.

Passaggio 1: avvio dell'installazione

Il processo di installazione inizia in modo diverso a seconda della fonte:

  • Play Store: L'app Play Store scarica l'APK (o gli APK suddivisi) e chiama il programma di installazione dei pacchetti del sistema con privilegi speciali che ignorano alcune conferme dell'utente.
  • Caricamento laterale: Quando si apre un file APK, Android avvia l'attività di installazione del pacchetto. Su Android 8.0 e versioni successive, l'app da installare deve disporre dell'autorizzazione "Installa app sconosciute" per la sua origine specifica.
  • ADB: Il comando adb install comunica direttamente con il servizio di gestione pacchetti tramite USB, ignorando completamente il programma di installazione grafico.

Indipendentemente dalla fonte, tutte le installazioni alla fine raggiungono lo stesso servizio di sistema: lo PackageManagerService (PMS). Questa è l'autorità centrale per tutte le operazioni sui pacchetti su Android.

Passaggio 2: analisi del pacchetto

Prima di ogni altra cosa, il sistema deve capire cosa sta per installare. PackageManagerService richiama PackageParser per leggere il file APK ed estrarne i metadati.

Il parser legge il file AndroidManifest.xml dall'APK. Questo file XML binario contiene informazioni critiche:

  • Nome del pacchetto: L'identificatore univoco dell'app (ad esempio, com.example.myapp)
  • Codice e nome della versione: Utilizzato per determinare se si tratta di un aggiornamento o di una nuova installazione
  • Versioni minime e di destinazione dell'SDK: Determina la compatibilità con il dispositivo
  • Permessi dichiarati: Entrambe le autorizzazioni richieste dall'app e le autorizzazioni personalizzate che definisce
  • Componenti: Attività, servizi, ricevitori di trasmissione e fornitori di contenuti registrati dall'app
  • Caratteristiche hardware e software: Requisiti come fotocamera, GPS o versioni OpenGL specifiche

Se il manifest non ha un formato corretto o la struttura dell'APK non è valida, l'installazione non riesce in questa fase con un messaggio "Errore di analisi". Questo è uno dei motivi più comuni per cui gli APK trasferiti localmente non vengono installati.

Passaggio 3: controlli di compatibilità

Una volta analizzato il manifest, il sistema esegue una serie di controlli di compatibilità:

  • Versione dell'SDK: Se il livello minSdkVersion dell'app è superiore al livello API del dispositivo, l'installazione viene rifiutata.
  • Compatibilità ABI: Se l'APK contiene librerie native, il sistema verifica se corrispondono all'architettura della CPU del dispositivo. Un APK con solo le librerie armeabi-v7a non verrà installato su un dispositivo solo x86.
  • Funzionalità richieste: Se l'app dichiara le funzionalità hardware richieste (come android.hardware.telephony), il sistema verifica che il dispositivo le supporti.
  • Spazio di archiviazione disponibile: Il sistema controlla se c'è abbastanza spazio libero per installare l'app, incluso lo spazio per le librerie native estratte e i file DEX ottimizzati.

Passaggio 4: verifica della firma

Questo è uno dei passaggi più critici nel processo di installazione. Android verifica la firma crittografica dell'APK per garantirne l'integrità e l'autenticità.

Il processo di verifica dipende da quali schemi di firma sono presenti:

Firma V1 (firma JAR)

Il sistema controlla la directory META-INF/ per i file di firma (.SF, .RSA o .DSA). Ogni file nell'APK viene verificato rispetto ai digest elencati nel manifest. Questo è lento perché ogni file deve essere sottoposto ad hashing individualmente.

Firma V2 (schema di firma APK v2)

Introdotto in Android 7.0, questo schema firma l'intero APK come un blob binario. Il blocco della firma viene inserito tra la directory centrale ZIP e il record di fine directory centrale. La verifica è molto più veloce perché opera sui byte grezzi senza la necessità di decomprimere le singole voci.

Firma V3 (rotazione chiave)

Disponibile da Android 9.0, V3 estende V2 con il supporto per la rotazione delle chiavi. Include una struttura di prova di rotazione che collega le chiavi di firma vecchie e nuove, consentendo agli sviluppatori di modificare la chiave di firma mantenendo la compatibilità degli aggiornamenti.

Firma V4 (incrementale)

Android 11 ha introdotto la V4 per installazioni incrementali. Fornisce una firma basata su albero Merkle che consente la verifica dei singoli blocchi mentre vengono trasmessi in streaming al dispositivo.

Se per qualsiasi motivo la verifica della firma fallisce, l'installazione viene immediatamente interrotta. Puoi controllare la firma di un APK prima dell'installazione utilizzando il nostro Strumento di verifica APK.

Aggiorna la corrispondenza della firma

Se è già installata un'app con lo stesso nome di pacchetto, il sistema effettua un ulteriore controllo: il certificato di firma del nuovo APK deve corrispondere al certificato di installazione esistente. Ciò impedisce a un malintenzionato di sostituire un'app legittima con una versione manomessa. Se le firme non corrispondono, verrà visualizzato l'errore "App non installata: il pacchetto è in conflitto con un pacchetto esistente con lo stesso nome".

Passaggio 5: conferma dell'utente

Per le installazioni trasferite localmente, il sistema visualizza una finestra di dialogo di conferma dell'installazione che mostra:

  • Il nome e l'icona dell'app (estratti dalle risorse dell'APK)
  • Autorizzazioni richieste dall'app (nelle versioni Android precedenti)
  • Che si tratti di una nuova installazione o di un aggiornamento
  • Eventuali avvisi sull'origine dell'app o sui potenziali rischi

Su Android 12 e versioni successive, la schermata di conferma è più semplice poiché le autorizzazioni di runtime vengono concesse individualmente quando l'app ne ha bisogno per la prima volta, anziché al momento dell'installazione.

Passaggio 6: estrazione e posizionamento dei file

Una volta che l'utente conferma (o, per le installazioni del Play Store, automaticamente), il sistema inizia a estrarre e posizionare i file:

Archiviazione APK

Il file APK stesso viene copiato in /data/app/[package-name]-[random]/base.apk. Per le installazioni APK divise, file aggiuntivi come split_config.arm64_v8a.apk vengono posizionati accanto all'APK di base. L'APK originale nella cartella Download non viene modificato né eliminato.

Estrazione della libreria nativa

Se l'APK contiene librerie native (nella directory lib/, queste vengono estratte in /data/app/[package-name]-[random]/lib/[abi]/). Nelle versioni Android più recenti, le app possono scegliere di mantenere compresse le librerie native all'interno dell'APK e caricarle direttamente utilizzando android:extractNativeLibs="false", risparmiando spazio di archiviazione.

Creazione della directory dei dati

Il sistema crea la directory dei dati privati ​​dell'app su /data/data/[package-name]/ (o /data/user/0/[package-name]/ su dispositivi multiutente). Questa directory è di proprietà di un UID Linux univoco assegnato all'app, garantendo che nessun'altra app possa accedervi senza privilegi di root.

Passaggio 7: ottimizzazione DEX

In questo passaggio Android trasforma il bytecode dell'app in un formato ottimizzato per l'hardware specifico del dispositivo. Il processo si è evoluto in modo significativo nel corso della storia di Android:

L'era Dalvik (Android 4.4 e versioni precedenti)

La macchina virtuale Dalvik originale utilizzava la compilazione Just-In-Time (JIT). Durante l'installazione, il file classes.dex è stato ottimizzato in un file ODEX che conteneva bytecode verificato e ottimizzato. Si trattava di un processo relativamente veloce, ma significava che l'app veniva eseguita più lentamente in fase di runtime poiché la maggior parte del codice veniva ancora interpretata.

ART con AOT (Android da 5.0 a 6.0)

Android Runtime (ART) ha sostituito Dalvik e ha introdotto la compilazione Ahead-Of-Time (AOT). Durante l'installazione, l'intero bytecode DEX è stato compilato in codice macchina nativo. Ciò ha reso le app più veloci, ma ha aumentato significativamente i tempi di installazione e l'utilizzo dello spazio di archiviazione. L'installazione di alcune app ha richiesto diversi minuti.

Compilazione guidata dal profilo (Android 7.0+)

Il moderno Android utilizza un approccio ibrido. Durante l'installazione vengono compilati solo i percorsi di avvio critici. Mentre l'utente esegue l'app, il sistema raccoglie i profili di esecuzione che identificano i percorsi del codice utilizzati di frequente. Durante la manutenzione inattiva (in genere durante la ricarica durante la notte), il sistema compila questi percorsi attivi in ​​codice nativo. Ciò bilancia la velocità di installazione, l'utilizzo dello spazio di archiviazione e le prestazioni di runtime.

Il codice compilato viene archiviato in /data/dalvik-cache/ o insieme all'APK come file .odex, .vdex e .art. Il file .vdex contiene codice DEX verificato, il file .odex contiene codice nativo compilato e il file .art contiene immagini heap preinizializzate per un avvio più rapido.

Passaggio 8: registrazione dell'autorizzazione

Il PackageManagerService registra le autorizzazioni e i componenti dichiarati dell'app nel sistema:

  • Autorizzazioni al momento dell'installazione (come INTERNET o VIBRATE vengono concessi automaticamente senza l'interazione dell'utente).
  • Autorizzazioni di esecuzione (come CAMERA o LOCATION sono registrati ma non concessi). L'app deve richiederli in fase di runtime.
  • Filtri di intenti sono registrati in modo che il sistema sappia quali app possono gestire quali azioni (come l'apertura di un URL o la condivisione di contenuti).
  • Fornitori di contenuti sono registrati presso le loro autorità in modo che altre app possano interrogarli.

Passaggio 9: integrazione del sistema

I passaggi finali integrano l'app nel sistema Android:

  • Aggiornamento del database dei pacchetti: Il database dei pacchetti del sistema (/data/system/packages.xml viene aggiornato con le informazioni della nuova app, inclusi l'UID assegnato, le autorizzazioni e le dichiarazioni dei componenti).
  • Notifica di avvio: Il launcher della schermata iniziale riceve una notifica della nuova app in modo che possa visualizzare l'icona dell'app.
  • Trasmissione: Il sistema invia una trasmissione PACKAGE_ADDED, consentendo ad altre app di reagire alla nuova installazione (ad esempio, le app di backup potrebbero pianificare un backup).
  • Contesto SELinux: I file dell'app sono etichettati con il contesto di sicurezza SELinux appropriato in base alla versione dell'SDK di destinazione e alle autorizzazioni dichiarate.

Perché le installazioni falliscono

Comprendere la pipeline di installazione aiuta a diagnosticare gli errori più comuni:

  • "Errore di analisi": L'APK è danneggiato, incompleto o presenta un file manifest non valido. Ciò accade spesso con download incompleti o file convertiti in modo errato.
  • "App non installata" (mancata corrispondenza della firma): Stai tentando di aggiornare un'app con un APK firmato da una chiave diversa. È necessario prima disinstallare la versione esistente.
  • "Spazio di archiviazione insufficiente": Spazio insufficiente per l'APK, le librerie estratte e l'output di ottimizzazione DEX. Lo spazio effettivo necessario è in genere 2-3 volte la dimensione dell'APK.
  • "Il pacchetto è in conflitto con il pacchetto esistente": Stesso nome del pacchetto ma firma diversa. Comune quando si passa dal Play Store alle versioni trasferite localmente.
  • Downgrade della versione bloccato: Per impostazione predefinita, Android impedisce l'installazione di una versione precedente su una nuova. ADB può sovrascriverlo con adb install -d.

Installazione dell'APK diviso

Quando si installano APK suddivisi (dagli app bundle), il processo è leggermente diverso. Il sistema utilizza un'API installazione basata su sessioni:

  1. Viene creata una nuova sessione di installazione
  2. Ogni APK diviso viene scritto nella sessione
  3. La sessione viene impegnata, attivando la pipeline di verifica completa
  4. Tutte le suddivisioni devono avere nomi di pacchetto, codici di versione e certificati di firma corrispondenti

Questo è il meccanismo utilizzato dagli installatori XAPK e da strumenti come il nostro Fusione da APKS a APK per gestire installazioni multi-file.

Installazione tramite ADB

Quando utilizzi adb install, il processo ignora il programma di installazione grafico ma segue la stessa pipeline interna. ADB comunica con il servizio di gestione pacchetti tramite una connessione socket. Supporta flag aggiuntivi che non sono disponibili tramite la GUI:

  • -r: Sostituisci l'app esistente (consenti la reinstallazione)
  • -d: consente il downgrade della versione
  • -g: Concedi immediatamente tutte le autorizzazioni di runtime
  • -t: consente l'installazione di APK di solo test
  • --install-multiple: installa gli APK divisi in un'unica sessione

Cosa succede durante la disinstallazione

Per completezza, ecco cosa succede quando un'app viene rimossa:

  1. I processi dell'app vengono terminati
  2. L'APK e le librerie estratte vengono eliminati da /data/app/
  3. La directory dei dati privati ​​dell'app viene rimossa (a meno che l'utente non scelga di conservare i dati)
  4. I file della cache DEX compilati vengono eliminati
  5. Il database dei pacchetti viene aggiornato
  6. Viene inviata una trasmissione PACKAGE_REMOVED
  7. Il launcher rimuove l'icona dell'app

Tieni presente che i file specifici dell'app nella memoria esterna (/Android/data/[package]/ e /Android/obb/[package]/ vengono eliminati anche su Android 10 e versioni successive, grazie all'applicazione dell'archiviazione con ambito).

Perché comprendere PackageManager fa risparmiare tempo di debug

Il processo di installazione di Android è una sequenza attentamente orchestrata di controlli di sicurezza, operazioni sui file e integrazioni di sistema. Ogni passaggio ha uno scopo, dalla protezione degli utenti dalle app manomesse all'ottimizzazione delle prestazioni per l'hardware specifico. Quando le installazioni falliscono, l'errore solitamente punta a un passaggio specifico di questa pipeline e la comprensione del processo aiuta a diagnosticare e risolvere rapidamente i problemi.

L'installazione dal Play Store, il sideload manuale di un APK e il push di una build con ADB vengono tutti incanalati attraverso la stessa pipeline sottostante, quella che assicura che ogni app sul tuo dispositivo sia stata verificata, posizionata correttamente e ottimizzata per il tuo hardware.

Progettato e documentato dal signor Shaefale Sviluppatore capo e architetto di pacchetti Android • Verificato su Android 12-15

Mst Shaefale mantiene la fusione XAPK/APKS lato client, il parser del manifest binario e gli strumenti di firma APK v1+v2 su xapktoapk.com. Hai notato un comando obsoleto o una modifica del sistema operativo? Invia una nota editoriale.