Creazione di più APK per texture GL diverse

Se pubblichi la tua app su Google Play, devi creare e caricare un Android App Bundle. In questo modo, Google Play genera e pubblica automaticamente APK ottimizzati per la configurazione del dispositivo di ogni utente, in modo che scarichi solo il codice e le risorse di cui ha bisogno per eseguire la tua app. La pubblicazione di più APK è utile se non pubblichi su Google Play, ma devi creare, firmare e gestire ogni APK autonomamente.

Quando sviluppi la tua applicazione Android per sfruttare più APK su Google Play, è importante adottare fin dall'inizio alcune best practice e prevenire problemi inutili nel processo di sviluppo. Questa lezione mostra come creare più APK della tua app, ciascuno supportante un sottoinsieme diverso di formati delle texture OpenGL. Avrai anche alcuni strumenti necessari per rendere il più semplice possibile il mantenimento di un codebase più APK.

Verifica di aver bisogno di più APK

Quando cerchi di creare un'applicazione che funzioni su tutti i dispositivi Android disponibili, è naturale che l'applicazione abbia un aspetto ottimale su ogni singolo dispositivo, anche se non supportano tutti lo stesso set di texture GL. All'inizio potrebbe sembrare che il supporto di più APK sia la soluzione migliore, ma spesso non è così. La sezione Utilizzare un singolo APK della guida per gli sviluppatori relativa agli APK multipli include alcune informazioni utili su come eseguire questa operazione con un singolo APK, ad esempio su come rilevare i formati delle texture supportati in fase di runtime. A seconda della situazione, potrebbe essere più semplice raggruppare tutti i formati con la tua applicazione e scegliere semplicemente quale utilizzare per il runtime.

Se puoi, limitare l'applicazione a un singolo APK offre diversi vantaggi, tra cui:

  • Pubblicazione e test più semplici
  • Devi gestire un'unica base di codice
  • L'applicazione può adattarsi alle modifiche alla configurazione del dispositivo
  • Il ripristino delle app su più dispositivi funziona correttamente
  • Non devi preoccuparti delle preferenze di mercato, del comportamento degli "upgrade" da un APK all'altro o di quale APK sia associato a quale classe di dispositivi

Il resto di questa lezione presuppone che tu abbia studiato l'argomento, assorbito attentamente il materiale nelle risorse collegate e stabilito che più APK sono la strada giusta per la tua applicazione.

Crea un grafico dei requisiti

La Guida per gli sviluppatori Android fornisce un pratico riferimento di alcune delle texture supportate più comuni nella pagina support-gl-texture. Questa pagina contiene anche alcuni suggerimenti che indicano quali telefoni (o famiglie di telefoni) supportano particolari formati di texture. Tieni presente che in genere è consigliabile che uno degli APK supporti l'ETC1, poiché il formato di texture è supportato da tutti i dispositivi Android che supportano la specifica OpenGL ES 2.0.

Poiché la maggior parte dei dispositivi Android supporta più di un formato di texture, è necessario stabilire un ordine di preferenza. Crea un grafico che includa tutti i formati supportati dalla tua applicazione. La cella più a sinistra avrà la priorità più bassa (probabilmente sarà ETC1, un valore predefinito davvero solido in termini di prestazioni e compatibilità). Colora il grafico in modo che ogni cella rappresenti un APK.

ETC1 ATI PowerVR

Colorare il grafico non solo rende questa guida meno monocromatica, ma consente anche di semplificare la comunicazione all'interno del team. Ora puoi semplicemente fare riferimento a ogni APK come "blu", "verde" o "rosso", anziché "quello che supporta i formati delle texture ETC1" e così via.

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

Che tu stia modificando un'applicazione Android esistente o ne stia iniziando una da zero, questa è la prima cosa che devi fare al codice di base e di gran lunga la più importante. Tutto ciò che viene inserito nel progetto della libreria deve essere aggiornato una sola volta (ad esempio stringhe localizzate in base alla lingua, temi di colore, bug corretti nel codice condiviso), il che migliora i tempi di sviluppo e riduce la probabilità di errori che potrebbero essere stati facilmente evitati.

Nota: anche se i dettagli di implementazione su come creare e includere progetti di libreria non rientrano nell'ambito di questa lezione, puoi imparare rapidamente a leggere Creare una raccolta Android.

Se stai convertendo un'applicazione esistente in modo da utilizzare il supporto di più APK, perlustra il tuo codebase per trovare ogni file stringa localizzato, elenco di valori, colori del tema, icone dei menu e layout che non cambieranno da un APK all'altro, poi inserisci tutto nel progetto della libreria. Anche il codice che non cambierà molto deve essere inserito nel progetto della libreria. Probabilmente dovrai estendere queste classi per aggiungere uno o due metodi da un APK all'altro.

Se invece crei l'applicazione da zero, prova a scrivere il codice nel progetto della libreria prima, poi spostalo in un singolo APK solo se necessario. A lungo termine, è molto più facile da gestire che aggiungerlo a uno, poi a un altro, a un altro e infine mesi dopo cercare di capire se il blob può essere spostato nella sezione della libreria senza rovinare nulla.

Creare nuovi progetti APK

Deve essere presente un progetto Android separato per ogni APK che vuoi rilasciare. Per una facile organizzazione, posiziona il progetto della libreria e tutti i progetti APK correlati nella stessa cartella principale. Inoltre, ricorda che ogni APK deve avere lo stesso nome del pacchetto, anche se non necessariamente deve condividerlo con la libreria. Se avessi 3 APK che seguono lo schema descritto in precedenza, la tua directory principale 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 estendila nel progetto APK. Avere un'attività iniziale definita nel progetto della libreria ti offre la possibilità di riunire 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 alcune semplici regole:

  • Il file manifest deve indicare che il determinato APK è idoneo
  • Tra gli APK idonei, vince il numero di versione più alto
  • Se uno dei formati delle texture elencati nel tuo APK è supportato dal dispositivo sul mercato, il dispositivo è considerato idoneo

Per quanto riguarda le texture GL, l'ultima regola è importante. Ciò significa che, ad esempio, devi prestare molto attenzione a utilizzare formati GL diversi nella stessa applicazione. Se utilizzi PowerVR il 99% delle volte, ma utilizzi ETC1 per, ad esempio, la schermata di benvenuto… In questo caso, il manifest deve necessariamente indicare il supporto di entrambi i formati. Un dispositivo che supporta solo ETC1 sarebbe considerato compatibile, la tua app verrebbe scaricata e l'utente vedrebbe alcuni emozionanti messaggi di arresto anomalo. In genere, se utilizzi più APK specificamente per scegliere come target diversi dispositivi in base al supporto delle texture GL, verrà utilizzato un formato texture per APK.

Questo in realtà rende il supporto delle texture un po' diverso rispetto alle altre due dimensioni APK, livello API e dimensioni dello schermo. Ogni dispositivo ha un solo livello API e una sola dimensione dello schermo ed è compito dell'APK supportare una serie di dispositivi. Con le texture, in genere l'APK supporta una texture e il dispositivo molte. Spesso si verificano sovrapposizioni in termini di un dispositivo che supporta molti APK, ma la soluzione è la stessa: i codici di versione.

A titolo esemplificativo, prendi alcuni dispositivi e controlla quanti degli APK definiti in precedenza sono adatti a ciascun dispositivo.

FooPhone Nexus S Evo
ETC1 ETC1 ETC1
PowerVR TC di ATI

Supponendo che i formati PowerVR e ATI siano entrambi preferiti rispetto a ETC1 quando disponibile, rispetto alla regola "il numero di versione più alto vince", se impostiamo l'attributo versionCode in ogni APK in modo che rosso ≥ verde ≥ blu, allora sia il rosso che il verde saranno sempre scelti rispetto al blu sui dispositivi che li supportano; se arriva un dispositivo che supporta sia il rosso che il verde, verrà scelto il rosso.

Per mantenere tutti gli APK in "canali" separati, è importante avere uno schema di codici di versione valido. Quello consigliato è disponibile nell'area Codici versione della nostra guida per gli sviluppatori. Poiché l'insieme di APK di esempio riguarda solo una delle tre possibili dimensioni, sarebbe sufficiente separare ogni APK per 1000 e incrementare da lì. Potrebbe avere il seguente aspetto:

Blu: 1001, 1002, 1003, 1004…
Verde: 2001, 2002, 2003, 2004…
Rosso:3001, 3002, 3003, 3004...

Mettendo tutto insieme, i manifest di Android dovrebbero avere il seguente aspetto:

Blu:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
    ...

Verde:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
    ...

Rosso:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" />
    ...

Controlla l'elenco di controllo pre-lancio

Prima di caricare l'app su Google Play, controlla i seguenti elementi. Ricorda che si tratta di elementi specificamente pertinenti 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 del pacchetto
  • Tutti gli APK devono essere firmati con lo stesso certificato
  • Controlla attentamente che i filtri manifest non contengano informazioni in conflitto (un APK che supporta solo Cupcake su schermi XLARGE non verrà visto da nessuno)
  • Il file manifest di ogni APK deve essere univoco per almeno una delle seguenti funzionalità supportate: schermo, texture OpenGL o versione della piattaforma
  • Prova a testare ogni APK su almeno un dispositivo. A parte questo, hai uno degli emulatori di dispositivi più personalizzabili sul tuo computer di sviluppo. Divertiti!

Vale anche la pena ispezionare l'APK compilato prima di lanciarlo sul mercato, per assicurarti che non ci siano sorprese che potrebbero nascondere la tua applicazione su Google Play. È piuttosto semplice usare lo strumento "aapt". Aapt (Android Asset Packaging Tool) fa parte del processo di compilazione per la creazione e il packaging delle applicazioni Android ed è anche uno strumento molto utile per ispezzionarle.

>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: 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

Quando esamini l'output di aapt, assicurati di non avere valori in conflitto per support-screens e compatible-screens e di non avere valori "uses-feature" indesiderati aggiunti a seguito delle autorizzazioni impostate nel file manifest. Nell'esempio precedente, l'APK sarà invisibile alla maggior parte dei dispositivi, se non a tutti.

Perché? Aggiungendo l'autorizzazione richiesta SEND_SMS, è stato aggiunto implicitamente il requisito della funzionalità android.hardware.telephony. Poiché la maggior parte (se non tutti) dei dispositivi di grandi dimensioni sono tablet senza hardware di telefonia, Google Play escluderà questo APK in questi casi, fino a quando non verranno lanciati dispositivi futuri che siano sufficientemente grandi da essere segnalati come di grandi dimensioni e che dispongono di hardware di telefonia.

Per fortuna, il problema si risolve facilmente aggiungendo quanto segue al file manifest:

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

Viene aggiunto anche il requisito android.hardware.touchscreen in modo implicito. 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 ciò avviene, esegui un ultimo controllo. Scarica l'applicazione su eventuali dispositivi di test per assicurarti che gli APK abbiano come target i dispositivi previsti. Congratulazioni, hai finito.