Creare più APK per diversi livelli API

Se pubblichi la tua app su Google Play, devi creare e caricare un Android App Bundle. Se lo fai, Google Play genera e pubblica automaticamente APK ottimizzati per la configurazione del dispositivo di ogni utente, in modo che gli utenti scarichino solo il codice e le risorse necessarie per eseguire la tua app. La pubblicazione di più APK è utile se non pubblichi su Google Play, ma devi creare, firmare e gestire personalmente ogni APK.

Quando sviluppi la tua applicazione Android in modo da sfruttare più APK su Google Play, è importante adottare alcune best practice fin dall'inizio ed evitare inutili grattacapi durante il processo di sviluppo. Questa lezione spiega come creare più APK della tua app, ciascuno relativo a una gamma leggermente diversa di livelli API. Avrai anche gli strumenti necessari per mantenere il più indolore possibile la gestione di più codebase di APK.

Conferma di aver bisogno di più APK

Quando cerchi di creare un'applicazione che funzioni su più generazioni della piattaforma Android, vuoi naturalmente che l'applicazione sfrutti le nuove funzionalità sui nuovi dispositivi, senza sacrificare la compatibilità con le versioni precedenti. All'inizio può sembrare che il supporto di più APK sia la soluzione migliore, ma spesso non è così. La sezione relativa all'utilizzo di un singolo APK della guida per gli sviluppatori con più APK include alcune informazioni utili su come risolvere questo problema con un singolo APK, incluso l'uso della nostra libreria di supporto. In questo articolo puoi anche imparare a scrivere codice che viene eseguito solo a determinati livelli di API in un singolo APK, senza ricorrere a tecniche costose di calcolo come la riflessione.

Se sei in grado di gestirla, limitare la tua applicazione a un singolo APK presenta diversi vantaggi, tra cui:

  • Pubblicazione e test più semplici
  • C'è un solo codebase da mantenere
  • L'applicazione può adattarsi alle modifiche alla configurazione del dispositivo
  • Il ripristino delle app su tutti i dispositivi funziona sempre
  • Non devi preoccuparti delle preferenze del mercato, del comportamento degli "upgrade" da un APK al successivo o dell'APK abbinato alla classe di dispositivi.

Nella parte restante di questa lezione si presuppone che tu abbia effettuato ricerche sull'argomento, analizzato attentamente il materiale presente nelle risorse collegate e stabilito che più APK siano la strada giusta per la tua applicazione.

Crea un grafico dei tuoi requisiti

Per iniziare, crea un semplice grafico per determinare rapidamente il numero di APK di cui hai bisogno e l'intervallo di API coperto da ogni APK. Come riferimento pratico, la pagina Versioni piattaforma del sito web per sviluppatori Android fornisce dati sul numero relativo di dispositivi attivi su cui è in esecuzione una determinata versione della piattaforma Android. Inoltre, anche se all'inizio può sembrare facile, tenere traccia di quale insieme di livelli API verrà scelto come target da ogni APK diventa piuttosto rapidamente difficile, soprattutto in caso di sovrapposizioni (spesso ce ne sono). Fortunatamente, è facile tracciare le tue esigenze in modo rapido e semplice e avere a disposizione un riferimento pratico per un secondo momento.

Per creare più grafici APK, inizia con una riga di celle che rappresentano i vari livelli API della piattaforma Android. Aggiungi una cella aggiuntiva alla fine per rappresentare le versioni future di Android.

3 4 5 6 7 8 9 10 11 12 13 +

Ora basta il colore del grafico in modo che ogni colore rappresenti un APK. Ecco un esempio di come puoi applicare ogni APK a un determinato intervallo di livelli API.

3 4 5 6 7 8 9 10 11 12 13 +

Una volta creato il grafico, distribuiscilo al tuo team. La comunicazione di gruppo sul tuo progetto è diventata immediatamente più semplice, dal momento che invece di chiedere "Com'è l'APK per i livelli API dal 3 al 6, eh, sai, quello per Android 1.x." Come va?" Puoi dire semplicemente "Come sta arrivando l'APK blu?"

Inserisci tutto il codice e le risorse comuni in un progetto libreria

Che si tratti di modificare un'applicazione Android esistente o di avviarne una da zero, questa è la prima cosa da fare al codebase, e soprattutto la più importante. Tutto ciò che rientra nel progetto della libreria deve essere aggiornato una sola volta (pensa a stringhe localizzate nel linguaggio, temi a colori, bug corretti nel codice condiviso), il che riduce i tempi di sviluppo e la probabilità di errori che si sarebbero facilmente evitati.

Nota: i dettagli dell'implementazione di come creare e includere progetti di libreria esulano dall'ambito di questa lezione, ma puoi comunque mantenerti al passo leggendo l'articolo Creare una libreria Android.

Se stai convertendo un'applicazione esistente per utilizzare il supporto di più APK, cerca nel codebase ogni file di stringa localizzato, l'elenco di valori, i colori dei temi, le icone di menu e il layout che non cambierà da un APK a un altro, quindi inserisci tutto nel progetto libreria. Anche il codice che non cambierà molto dovrebbe essere inserito nel progetto della biblioteca. Probabilmente ti ritroverai a estendere queste classi per aggiungere uno o due metodi da APK ad APK.

Se, invece, stai creando l'applicazione da zero, prova prima il più possibile a scrivere codice nel progetto della libreria, quindi spostalo verso il basso su un singolo APK, se necessario. È molto più facile da gestire a lungo termine piuttosto che aggiungerlo a uno, quindi a un altro, poi a un altro e infine, mesi dopo, cercando di capire se il blob può essere spostato nella sezione della raccolta senza rovinare nulla.

Crea nuovi progetti APK

Dovrebbe esserci un progetto Android separato per ogni APK che intendi rilasciare. Per semplificare l'organizzazione, posiziona il progetto della libreria e tutti i progetti APK correlati nella stessa cartella principale. Ricorda inoltre che ogni APK deve avere lo stesso nome di pacchetto, anche se non è necessariamente necessario condividere il nome del pacchetto con la libreria. Se avessi 3 APK che seguono lo schema descritto in precedenza, la directory root potrebbe avere il seguente aspetto:

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-red

Una volta creati i progetti, aggiungi il progetto della libreria come riferimento a ogni progetto APK. Se possibile, definisci l'attività iniziale nel progetto della libreria ed estendi tale attività nel progetto APK. Avere un'attività iniziale definita nel progetto libreria ti offre la possibilità di mettere tutta l'inizializzazione dell'applicazione in un unico posto, in modo che ogni singolo APK non debba implementare nuovamente attività "universali", come l'inizializzazione di Analytics, l'esecuzione di controlli delle licenze e qualsiasi altra procedura di inizializzazione che non cambia molto da un APK all'altro.

Modificare i manifest

Quando un utente scarica un'applicazione che utilizza più APK tramite Google Play, l'APK corretto da utilizzare viene scelto seguendo due semplici regole:

  • Il file manifest deve indicare che l'APK specifico è idoneo
  • Tra gli APK idonei, prevale il numero di versione più alto

Ad esempio, prendiamo il set di più APK descritto in precedenza e supponiamo di non aver impostato un livello API massimo per nessuno degli APK. Considerato individualmente, l'intervallo possibile di ogni APK sarebbe simile a questo:

3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +

Poiché è necessario che un APK con un valore minSdkVersion più alto abbia anche un codice versione più elevato, sappiamo che, in termini di valori versionCode, rosso ≥ verde ≥ blu. Di conseguenza, possiamo effettivamente comprimere il grafico in questo modo:

3 4 5 6 7 8 9 10 11 12 13 +

Ora supponiamo che l'APK rosso abbia dei requisiti che gli altri due non hanno. La pagina Filtri su Google Play della Guida per gli sviluppatori Android contiene un elenco completo dei possibili colpevoli. Ad esempio, supponiamo che il rosso richieda una fotocamera anteriore. In effetti, lo scopo principale dell'APK rosso è combinare la fotocamera anteriore con una nuova dolce funzionalità aggiunta nell'API 11. Ma, si è scoperto che non tutti i dispositivi che supportano l'API 11 HANNO nemmeno fotocamere frontali! Che orrore!

Fortunatamente, se un utente naviga su Google Play da uno di questi dispositivi, Google Play esamina il manifest, vede che il rosso elenca la fotocamera anteriore come requisito e la ignora, dopo aver stabilito che Red e quel dispositivo non sono una corrispondenza perfetta nel paradiso digitale. Vedrà quindi che il colore verde non solo è compatibile con le versioni precedenti dei dispositivi con l'API 11 (dato che non è stato definito alcun valore maxSdkVersion), ma non importa se ci sia o meno una fotocamera anteriore. L'utente può comunque scaricare l'app da Google Play perché, nonostante l'intero incidente con la fotocamera anteriore, era comunque presente un APK che supportava quel particolare livello API.

Per mantenere tutti gli APK in "canali separati", è importante avere uno schema di codice di versione efficace. Quello consigliato è disponibile nell'area Codici di versione della nostra guida per gli sviluppatori. Poiché il set di APK di esempio riguarda solo una delle tre possibili dimensioni, sarebbe sufficiente separare ogni APK per 1000, impostare le prime due cifre sul valore minSdkVersion per quell'APK specifico e incrementare di conseguenza. L'URL potrebbe avere il seguente aspetto:

Blu: 03001, 03002, 03003, 03004...
Verde: 07001, 07002, 07003, 07004...
Rosso:11001, 11002, 11003, 11004...

Riassumendo, i file manifest Android probabilmente avrebbero il seguente aspetto:

Blu:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="03001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    ...

Verde:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="07001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="7" />
    ...

Rosso:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="11001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="11" />
    ...

Esamina l'elenco di controllo pre-lancio

Prima di eseguire il caricamento su Google Play, ricontrolla quanto segue. Ricorda che queste norme si riferiscono specificamente a più APK e non rappresentano in alcun modo un elenco di controllo completo per tutte le applicazioni caricate su Google Play.

  • Tutti gli APK devono avere lo stesso nome di pacchetto
  • Tutti gli APK devono essere firmati con lo stesso certificato
  • Se gli APK si sovrappongono nella versione della piattaforma, quello con il valore minSdkVersion più alto deve avere un codice versione più recente
  • Controlla se nei filtri del file manifest sono presenti informazioni contrastanti (gli APK che supportano soltanto i cupcake sulle schermate XLARGE non verranno visualizzati da nessuno)
  • Il file manifest di ogni APK deve essere univoco in almeno uno schermo supportato, una texture openGL o una versione della piattaforma
  • Prova a testare ogni APK su almeno un dispositivo. Salvo ciò, hai uno degli emulatori di dispositivi più personalizzabili nel settore che si trova sulla tua macchina di sviluppo. Pazzesco!

Vale anche la pena esaminare l'APK compilato prima di metterlo sul mercato, per assicurarti che non ci siano sorprese che potrebbero nascondere la tua applicazione su Google Play. Per farlo, basta usare lo strumento "aapt". Aapt (Android Asset Packaging Tool) fa parte del processo di creazione e pacchettizzazione delle applicazioni Android, oltre a essere uno strumento molto utile per ispezionarle.

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'small' 'normal' 'large' 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

Quando esamini l'output aapt, assicurati di non avere valori in conflitto per supports-screen e compatible-SCREEN e di non avere valori "uses-feature" non intenzionali aggiunti a seguito delle autorizzazioni impostate nel file manifest. Nell'esempio precedente, l'APK non sarà visibile a molti dispositivi.

Perché? Aggiungendo l'autorizzazione richiesta SEND_SMS, il requisito per le funzionalità di android.hardware.telephony è stato aggiunto implicitamente. Poiché l'API 11 è Honeycomb (la versione di Android ottimizzata specificamente per i tablet) e nessun dispositivo Honeycomb contiene hardware per la telefonia, Google Play filtrerà questo APK in tutti i casi, finché non arriveranno dispositivi futuri che abbiano un livello API superiore E possiedano hardware per la telefonia.

Fortunatamente, questo problema può essere facilmente risolto aggiungendo quanto segue al file manifest:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

Anche il requisito android.hardware.touchscreen viene aggiunto implicitamente. Se vuoi che il tuo APK sia visibile sulle TV che non sono dispositivi touchscreen, devi aggiungere quanto segue al file manifest:

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

Dopo aver completato l'elenco di controllo pre-lancio, carica gli APK su Google Play. Potrebbe essere necessario un po' di tempo prima che l'applicazione venga visualizzata durante la navigazione su Google Play, ma quando viene visualizzata devi eseguire un ultimo controllo. Scarica l'applicazione su tutti i dispositivi di test eventualmente in tuo possesso, per assicurarti che gli APK abbiano come target i dispositivi previsti. Congratulazioni, hai completato la procedura.