I moduli delle funzionalità ti consentono di separare determinate funzionalità e risorse dal modulo di base della tua app e includerle nell'app bundle. Tramite Play Feature Delivery, gli utenti possono, ad esempio, scaricare e installare successivamente i componenti on demand dopo che hanno già installato l'APK di base della tua app.
Ad esempio, prendi in considerazione un'app di messaggistica di testo che includa funzionalità per acquisire e inviare messaggi con immagini, ma solo una piccola percentuale di utenti invia messaggi con immagini. Potrebbe essere opportuno includere un messaggio con immagini come modulo di funzionalità scaricabile. In questo modo, il download iniziale dell'app è più ridotto per tutti gli utenti e solo quelli che inviano messaggi con immagini dovranno scaricare il componente aggiuntivo.
Tieni presente che questo tipo di modularizzazione richiede uno sforzo maggiore e possibilmente il refactoring del codice esistente della tua app, quindi valuta con attenzione quali funzionalità della tua app trarrebbero il massimo vantaggio dalla disponibilità per gli utenti on demand. Per comprendere meglio i casi d'uso e le linee guida ottimali per le funzionalità on demand, leggi le best practice per l'esperienza utente per la distribuzione on demand.
Se vuoi modularizzare gradualmente le funzionalità dell'app nel tempo, senza abilitare opzioni di distribuzione avanzate come la pubblicazione on demand, configura la distribuzione al momento dell'installazione.
Questa pagina ti consente di aggiungere un modulo di funzionalità al progetto della tua app e configurarlo per la distribuzione on demand. Prima di iniziare, assicurati di utilizzare Android Studio 3.5 o versioni successive e il plug-in Android Gradle 3.5.0 o versioni successive.
Configura un nuovo modulo per la distribuzione on demand
Il modo più semplice per creare un nuovo modulo di funzionalità è utilizzare Android Studio 3.5 o versioni successive. Poiché i moduli delle funzionalità hanno una dipendenza intrinseca dal modulo dell'app di base, puoi aggiungerli solo ai progetti di app esistenti.
Per aggiungere un modulo di funzionalità al progetto della tua app utilizzando Android Studio, procedi nel seguente modo:
- Se non l'hai ancora fatto, apri il progetto dell'app nell'IDE.
- Seleziona File > Nuovo > Nuovo modulo dalla barra dei menu.
- Nella finestra di dialogo Crea nuovo modulo, seleziona Modulo di funzionalità dinamiche e fai clic su Avanti.
- Nella sezione Configura il nuovo modulo, completa quanto segue:
- Seleziona il modulo Applicazione di base per il progetto dell'app dal menu a discesa.
- Specifica un Nome modulo. L'IDE utilizza questo nome per identificare il modulo come sottoprogetto Gradle nel file delle impostazioni di Gradle. Quando
crei l'app bundle, Gradle utilizza l'ultimo elemento del nome
del sottoprogetto per inserire l'attributo
<manifest split>
nel manifest del modulo delle funzionalità. - Specifica il nome del pacchetto del modulo. Per impostazione predefinita, Android Studio suggerisce un nome pacchetto che combina il nome del pacchetto principale del modulo di base e il nome del modulo specificato nel passaggio precedente.
- Seleziona il livello API minimo che il modulo deve supportare. Questo valore deve corrispondere a quello del modulo di base.
- Tocca Avanti.
Nella sezione Opzioni di download del modulo, completa quanto segue:
Specifica il titolo del modulo utilizzando fino a 50 caratteri. La piattaforma utilizza questo titolo per identificare il modulo agli utenti quando, ad esempio, per confermare se l'utente vuole scaricarlo. Per questo motivo, il modulo di base dell'app deve includere il titolo del modulo come risorsa stringa, che puoi tradurre. Durante la creazione del modulo utilizzando Android Studio, l'IDE aggiunge la risorsa stringa al modulo di base al posto tuo e inserisce la seguente voce nel file manifest del modulo delle funzionalità:
<dist:module ... dist:title="@string/feature_title"> </dist:module>
Nel menu a discesa in Inclusione al momento dell'installazione, seleziona Non includere il modulo al momento dell'installazione. Android Studio inserisce il seguente nel file manifest del modulo per riflettere la tua scelta:
<dist:module ... > <dist:delivery> <dist:on-demand/> </dist:delivery> </dist:module>
Seleziona la casella accanto a Fusing se vuoi che il modulo sia disponibile per i dispositivi con Android 4.4 (livello API 20) e versioni precedenti e sia incluso in APK multipli. Ciò significa che puoi attivare il comportamento on demand per questo modulo e disattivare il fusing per ometterlo dai dispositivi che non supportano il download e l'installazione di APK divisi. Android Studio inserisce il seguente nel file manifest del modulo per riflettere la tua scelta:
<dist:module ...> <dist:fusing dist:include="true | false" /> </dist:module>
Fai clic su Fine.
Dopo che Android Studio ha finito di creare il modulo, esaminane i contenuti dal riquadro Progetto (seleziona Visualizza > Finestre strumenti > Progetto dalla barra dei menu). Il codice, le risorse e l'organizzazione predefiniti devono essere simili a quelli del modulo dell'app standard.
Dopodiché dovrai implementare la funzionalità di installazione on demand utilizzando la libreria Play Feature Delivery.
Includi la libreria Play Feature Delivery nel progetto
Prima di poter iniziare, devi aggiungere la libreria Play Feature Delivery al tuo progetto.
Richiedi un modulo on demand
Se la tua app deve utilizzare un modulo di funzionalità, può richiederne uno
mentre è in primo piano per la classe
SplitInstallManager
. Quando effettui una
richiesta, la tua app deve specificare il nome del modulo come definito
dall'elemento split
nel manifest del modulo di destinazione. Quando crei un modulo di funzionalità con Android Studio, il sistema di compilazione utilizza il Nome modulo fornito per inserire questa proprietà nel manifest del modulo al momento della compilazione.
Per ulteriori informazioni, leggi la pagina relativa ai manifest dei moduli delle funzionalità.
Ad esempio, prendi in considerazione un'app che dispone di un modulo on demand per acquisire e inviare
messaggi con immagine utilizzando la fotocamera del dispositivo e questo modulo on demand
specifica split="pictureMessages"
nel file manifest. Il seguente esempio utilizza SplitInstallManager
per richiedere il modulo pictureMessages
(insieme a un modulo aggiuntivo per alcuni filtri promozionali):
Kotlin
// Creates an instance of SplitInstallManager. val splitInstallManager = SplitInstallManagerFactory.create(context) // Creates a request to install a module. val request = SplitInstallRequest .newBuilder() // You can download multiple on demand modules per // request by invoking the following method for each // module you want to install. .addModule("pictureMessages") .addModule("promotionalFilters") .build() splitInstallManager // Submits the request to install the module through the // asynchronous startInstall() task. Your app needs to be // in the foreground to submit the request. .startInstall(request) // You should also be able to gracefully handle // request state changes and errors. To learn more, go to // the section about how to Monitor the request state. .addOnSuccessListener { sessionId -> ... } .addOnFailureListener { exception -> ... }
Java
// Creates an instance of SplitInstallManager. SplitInstallManager splitInstallManager = SplitInstallManagerFactory.create(context); // Creates a request to install a module. SplitInstallRequest request = SplitInstallRequest .newBuilder() // You can download multiple on demand modules per // request by invoking the following method for each // module you want to install. .addModule("pictureMessages") .addModule("promotionalFilters") .build(); splitInstallManager // Submits the request to install the module through the // asynchronous startInstall() task. Your app needs to be // in the foreground to submit the request. .startInstall(request) // You should also be able to gracefully handle // request state changes and errors. To learn more, go to // the section about how to Monitor the request state. .addOnSuccessListener(sessionId -> { ... }) .addOnFailureListener(exception -> { ... });
Quando la tua app richiede un modulo on demand, la libreria Play Feature Delivery utilizza una strategia "Accendi e elimina". In altre parole, invia la richiesta per scaricare il modulo alla piattaforma, ma non monitora se l'installazione è riuscita. Per far progredire il percorso dell'utente dopo l'installazione o per gestire correttamente gli errori, assicurati di monitorare lo stato della richiesta.
Nota: è possibile richiedere un modulo di funzionalità già installato sul dispositivo. L'API considera immediatamente la richiesta come completata se rileva che il modulo è già installato. Inoltre, dopo l'installazione di un modulo, Google Play lo mantiene aggiornato automaticamente. In altre parole, quando carichi una nuova versione dell'app bundle, la piattaforma aggiorna tutti gli APK installati che appartengono alla tua app. Per ulteriori informazioni, leggi Gestire gli aggiornamenti delle app.
Per accedere al codice e alle risorse del modulo, la tua app deve abilitare SplitCompat. Tieni presente che SplitCompat non è necessario per le app istantanee Android.
Rimanda l'installazione di moduli on demand
Se non è necessario che l'app scarichi e installi immediatamente un modulo on demand, puoi posticipare l'installazione quando l'app è in background. Ad esempio, se vuoi precaricare del materiale promozionale per un lancio successivo dell'app.
Puoi specificare un modulo da scaricare in un secondo momento utilizzando il metodo deferredInstall()
, come mostrato di seguito. Inoltre, a differenza di
SplitInstallManager.startInstall()
,
la tua app non deve essere in primo piano per avviare una richiesta di
installazione differita.
Kotlin
// Requests an on demand module to be downloaded when the app enters // the background. You can specify more than one module at a time. splitInstallManager.deferredInstall(listOf("promotionalFilters"))
Java
// Requests an on demand module to be downloaded when the app enters // the background. You can specify more than one module at a time. splitInstallManager.deferredInstall(Arrays.asList("promotionalFilters"));
Le richieste per installazioni differite sono eseguite secondo il criterio del "best effort" e non puoi monitorarne l'avanzamento. Pertanto, prima di tentare di accedere a un modulo che hai specificato per l'installazione differita, devi verificare che il modulo sia stato installato. Se
il modulo deve essere disponibile immediatamente, utilizza
SplitInstallManager.startInstall()
per richiederlo, come mostrato nella sezione
precedente.
Monitora lo stato della richiesta
Per poter aggiornare una barra di avanzamento, attivare un intent dopo
l'installazione o gestire agevolmente un errore di richiesta, devi ascoltare gli
aggiornamenti di stato dall'attività SplitInstallManager.startInstall()
asincrona.
Prima di poter iniziare a ricevere aggiornamenti per la tua richiesta di installazione, registra un
ascoltatore e ottieni l'ID sessione per la richiesta, come mostrato di seguito.
Kotlin
// Initializes a variable to later track the session ID for a given request. var mySessionId = 0 // Creates a listener for request status updates. val listener = SplitInstallStateUpdatedListener { state -> if (state.sessionId() == mySessionId) { // Read the status of the request to handle the state update. } } // Registers the listener. splitInstallManager.registerListener(listener) ... splitInstallManager .startInstall(request) // When the platform accepts your request to download // an on demand module, it binds it to the following session ID. // You use this ID to track further status updates for the request. .addOnSuccessListener { sessionId -> mySessionId = sessionId } // You should also add the following listener to handle any errors // processing the request. .addOnFailureListener { exception -> // Handle request errors. } // When your app no longer requires further updates, unregister the listener. splitInstallManager.unregisterListener(listener)
Java
// Initializes a variable to later track the session ID for a given request. int mySessionId = 0; // Creates a listener for request status updates. SplitInstallStateUpdatedListener listener = state -> { if (state.sessionId() == mySessionId) { // Read the status of the request to handle the state update. } }; // Registers the listener. splitInstallManager.registerListener(listener); ... splitInstallManager .startInstall(request) // When the platform accepts your request to download // an on demand module, it binds it to the following session ID. // You use this ID to track further status updates for the request. .addOnSuccessListener(sessionId -> { mySessionId = sessionId; }) // You should also add the following listener to handle any errors // processing the request. .addOnFailureListener(exception -> { // Handle request errors. }); // When your app no longer requires further updates, unregister the listener. splitInstallManager.unregisterListener(listener);
Gestire gli errori delle richieste
Tieni presente che l'installazione on demand dei moduli delle funzionalità a volte può non riuscire, proprio come l'installazione delle app non sempre riesce. La mancata installazione può essere dovuta a problemi quali lo spazio di archiviazione sul dispositivo in esaurimento, l'assenza di connettività di rete o l'impossibilità da parte dell'utente di accedere al Google Play Store. Per suggerimenti su come gestire queste situazioni in modo corretto dal punto di vista dell'utente, consulta le nostre linee guida per l'esperienza utente per la pubblicazione on demand.
A livello di codice, devi gestire gli errori di download o installazione di un modulo utilizzando addOnFailureListener()
, come mostrato di seguito:
Kotlin
splitInstallManager .startInstall(request) .addOnFailureListener { exception -> when ((exception as SplitInstallException).errorCode) { SplitInstallErrorCode.NETWORK_ERROR -> { // Display a message that requests the user to establish a // network connection. } SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED -> checkForActiveDownloads() ... } } fun checkForActiveDownloads() { splitInstallManager // Returns a SplitInstallSessionState object for each active session as a List. .sessionStates .addOnCompleteListener { task -> if (task.isSuccessful) { // Check for active sessions. for (state in task.result) { if (state.status() == SplitInstallSessionStatus.DOWNLOADING) { // Cancel the request, or request a deferred installation. } } } } }
Java
splitInstallManager .startInstall(request) .addOnFailureListener(exception -> { switch (((SplitInstallException) exception).getErrorCode()) { case SplitInstallErrorCode.NETWORK_ERROR: // Display a message that requests the user to establish a // network connection. break; case SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED: checkForActiveDownloads(); ... }); void checkForActiveDownloads() { splitInstallManager // Returns a SplitInstallSessionState object for each active session as a List. .getSessionStates() .addOnCompleteListener( task -> { if (task.isSuccessful()) { // Check for active sessions. for (SplitInstallSessionState state : task.getResult()) { if (state.status() == SplitInstallSessionStatus.DOWNLOADING) { // Cancel the request, or request a deferred installation. } } } }); }
Nella tabella che segue vengono descritti gli stati di errore che l'app potrebbe dover gestire:
Codice di errore | Descrizione | Azione suggerita |
---|---|---|
ACTIVE_SESSIONS_LIMIT_EXCEEDED | La richiesta è stata rifiutata perché esiste almeno una richiesta in fase di download. | Controlla se sono presenti richieste ancora in fase di download, come mostrato nell'esempio riportato sopra. |
MODULE_NON DISPONIBILE | Google Play non riesce a trovare il modulo richiesto in base alla versione installata corrente dell'app, del dispositivo e dell'account Google Play dell'utente. | Se l'utente non ha accesso al modulo, avvisalo. |
RICHIESTA_NON_VALIDA | Google Play ha ricevuto la richiesta, ma quest'ultima non è valida. | Verifica che le informazioni incluse nella richiesta siano complete e accurate. |
SESSIONE_NON_TROVATA | Impossibile trovare una sessione per un determinato ID sessione. | Se stai cercando di monitorare lo stato di una richiesta in base al suo ID sessione, assicurati che l'ID sessione sia corretto. |
API_NOT_AVAILABLE | La libreria Play Feature Delivery non è supportata sul dispositivo corrente. Questo significa che il dispositivo non può scaricare e installare funzionalità on demand. | Per i dispositivi con Android 4.4 (livello API 20) o versioni precedenti, devi
includere i moduli delle funzionalità al momento dell'installazione utilizzando la
proprietà manifest dist:fusing . Per saperne di più, scopri di più sul
manifest del modulo delle funzionalità.
|
ERRORE_RETE | La richiesta non è riuscita a causa di un errore di rete. | Chiedi all'utente di stabilire una connessione di rete o di passare a un'altra rete. |
ACCESSO_NEGATO | L'app non è in grado di registrare la richiesta a causa di autorizzazioni insufficienti. | Questo accade solitamente quando l'app è in background. Quando l'app torna in primo piano, prova a eseguire la richiesta. |
INCOMPATIBILE_CON_SESSION_ESISTENTE | La richiesta contiene uno o più moduli già richiesti, ma non ancora installati. | Crea una nuova richiesta che non includa moduli già richiesti dalla tua
app o attendi il completamento dell'installazione di tutti i moduli attualmente richiesti
prima di riprovare.
Tieni presente che la richiesta di un modulo già installato non genera un errore. |
SERVIZIO_DIED | Il servizio responsabile della gestione della richiesta è terminato. | Riprova a inviare la richiesta.
|
ARCHIVIAZIONE_INSUFFICIENTE | Lo spazio di archiviazione sul dispositivo non è sufficiente per installare il modulo delle funzionalità. | Comunica all'utente che non dispone di spazio di archiviazione sufficiente per installare questa funzionalità. |
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR | Impossibile caricare il modulo delle funzionalità da SplitCompat. | Questi errori dovrebbero risolversi automaticamente dopo il successivo riavvio dell'app. |
PLAY_STORE_NOT_FOUND | L'app Play Store non è installata sul dispositivo. | Comunica all'utente che per scaricare questa funzionalità è necessaria l'app Play Store. |
APP_NON_POSITIVA | L'app non è stata installata da Google Play e la funzionalità non può essere scaricata. Questo errore può verificarsi solo per le installazioni differite. | Se vuoi che l'utente acquisisca l'app su Google Play, usa
startInstall() , che può ottenere la
conferma dell'utente necessaria. |
ERRORE_INTERNO | Si è verificato un errore interno nel Play Store. | Riprova a inviare la richiesta. |
Se un utente richiede il download di un modulo on demand e si verifica un errore, valuta la possibilità di visualizzare una finestra di dialogo con due opzioni per l'utente: Riprova (che tenta nuovamente la richiesta) e Annulla (che abbandona la richiesta). Per ulteriore assistenza, dovresti anche fornire il link della Guida che indirizza gli utenti al Centro assistenza Google Play.
Gestire gli aggiornamenti dello stato
Dopo aver registrato un listener e registrato l'ID sessione per la tua richiesta,
utilizza StateUpdatedListener.onStateUpdate()
per gestire le modifiche di stato, come mostrato di seguito.
Kotlin
override fun onStateUpdate(state : SplitInstallSessionState) { if (state.status() == SplitInstallSessionStatus.FAILED && state.errorCode() == SplitInstallErrorCode.SERVICE_DIED) { // Retry the request. return } if (state.sessionId() == mySessionId) { when (state.status()) { SplitInstallSessionStatus.DOWNLOADING -> { val totalBytes = state.totalBytesToDownload() val progress = state.bytesDownloaded() // Update progress bar. } SplitInstallSessionStatus.INSTALLED -> { // After a module is installed, you can start accessing its content or // fire an intent to start an activity in the installed module. // For other use cases, see access code and resources from installed modules. // If the request is an on demand module for an Android Instant App // running on Android 8.0 (API level 26) or higher, you need to // update the app context using the SplitInstallHelper API. } } } }
Java
@Override public void onStateUpdate(SplitInstallSessionState state) { if (state.status() == SplitInstallSessionStatus.FAILED && state.errorCode() == SplitInstallErrorCode.SERVICE_DIES) { // Retry the request. return; } if (state.sessionId() == mySessionId) { switch (state.status()) { case SplitInstallSessionStatus.DOWNLOADING: int totalBytes = state.totalBytesToDownload(); int progress = state.bytesDownloaded(); // Update progress bar. break; case SplitInstallSessionStatus.INSTALLED: // After a module is installed, you can start accessing its content or // fire an intent to start an activity in the installed module. // For other use cases, see access code and resources from installed modules. // If the request is an on demand module for an Android Instant App // running on Android 8.0 (API level 26) or higher, you need to // update the app context using the SplitInstallHelper API. } } }
Gli stati possibili per la tua richiesta di installazione sono descritti nella tabella di seguito.
Stato richiesta | Descrizione | Azione suggerita |
---|---|---|
IN ATTESA | La richiesta è stata accettata e il download dovrebbe iniziare a breve. | Inizializza i componenti dell'interfaccia utente, ad esempio una barra di avanzamento, per fornire all'utente un feedback sul download. |
REQUIRES_USER_CONFIRMATION | Il download richiede la conferma dell'utente. In genere questo stato si verifica se l'app non è stata installata tramite Google Play. | Chiedere all'utente di confermare il download della funzionalità tramite Google Play. Per scoprire di più, vai alla sezione su come ottenere la conferma dell'utente. |
DOWNLOAD | Download in corso. | Se fornisci una barra di avanzamento per il download, usa i metodi SplitInstallSessionState.bytesDownloaded() e SplitInstallSessionState.totalBytesToDownload() per aggiornare la UI (vedi l'esempio di codice sopra questa tabella). |
SCARICATI | Il dispositivo ha scaricato il modulo, ma l'installazione non è ancora iniziata. | Le app dovrebbero abilitare SplitCompat per accedere ai moduli scaricati e non vedere questo stato. Questa operazione è necessaria per accedere al codice e alle risorse del modulo delle funzionalità. |
INSTALLAZIONE | Il dispositivo sta installando il modulo. | Aggiorna la barra di avanzamento. In genere questo stato è breve. |
INSTALLATA | Il modulo è installato sul dispositivo. | Accedi al codice e alla risorsa nel modulo per continuare il percorso dell'utente.
Se il modulo riguarda un'app istantanea Android con Android 8.0 (livello API 26) o versioni successive, devi utilizzare |
CONVALIDA NON RIUSCITA | La richiesta non è andata a buon fine prima dell'installazione del modulo sul dispositivo. | Chiedi all'utente di riprovare la richiesta o di annullarla. |
ANNULLAMENTO | Il dispositivo sta per annullare la richiesta. | Per scoprire di più, vai alla sezione su come annullare una richiesta di installazione. |
CANCELLATO | La richiesta è stata annullata. |
Ottenere la conferma dell'utente
In alcuni casi, Google Play potrebbe richiedere la conferma dell'utente prima di soddisfare una richiesta di download. Ad esempio, se la tua app non è stata installata da Google
Play o se stai tentando un download di grandi dimensioni tramite dati mobili. In questi casi,
lo stato della richiesta è REQUIRES_USER_CONFIRMATION
e la tua app
deve ricevere la conferma dell'utente prima che il dispositivo sia in grado di scaricare e
installare i moduli della richiesta. Per ottenere conferma, l'app deve
chiedere all'utente quanto segue:
Kotlin
override fun onSessionStateUpdate(state: SplitInstallSessionState) { if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) { // Displays a confirmation for the user to confirm the request. splitInstallManager.startConfirmationDialogForResult( state, // an activity result launcher registered via registerForActivityResult activityResultLauncher) } ... }
Java
@Override void onSessionStateUpdate(SplitInstallSessionState state) { if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) { // Displays a confirmation for the user to confirm the request. splitInstallManager.startConfirmationDialogForResult( state, // an activity result launcher registered via registerForActivityResult activityResultLauncher); } ... }
Puoi registrare un'Avvio app dei risultati di attività utilizzando il contratto integrato ActivityResultContracts.StartIntentSenderForResult
. Vedi API Activity Result.
Lo stato della richiesta viene aggiornato in base alla risposta dell'utente:
- Se l'utente accetta la conferma, lo stato della richiesta diventa
PENDING
e il download continua. - Se l'utente rifiuta la conferma, lo stato della richiesta diventa
CANCELED
. - Se l'utente non effettua una selezione prima dell'eliminazione della finestra di dialogo,
lo stato della richiesta rimane
REQUIRES_USER_CONFIRMATION
. La tua app può chiedere di nuovo all'utente di completare la richiesta.
Per ricevere un callback con la risposta dell'utente, puoi eseguire l'override di ActivityResultCallback come mostrato di seguito.
Kotlin
registerForActivityResult(StartIntentSenderForResult()) { result: ActivityResult -> { // Handle the user's decision. For example, if the user selects "Cancel", // you may want to disable certain functionality that depends on the module. } }
Java
registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { // Handle the user's decision. For example, if the user selects "Cancel", // you may want to disable certain functionality that depends on the module. } });
Annullare una richiesta di installazione
Se la tua app deve annullare una richiesta prima di essere installata, può richiamare
il metodo cancelInstall()
utilizzando l'ID sessione della richiesta, come mostrato di seguito.
Kotlin
splitInstallManager // Cancels the request for the given session ID. .cancelInstall(mySessionId)
Java
splitInstallManager // Cancels the request for the given session ID. .cancelInstall(mySessionId);
Accedi ai moduli
Per accedere al codice e alle risorse di un modulo scaricato dopo averlo scaricato, l'app deve abilitare la libreria SplitCompat per l'app e per ogni attività nei moduli delle funzionalità scaricati dall'app.
Tuttavia, è necessario notare che la piattaforma presenta le seguenti limitazioni per l'accesso ai contenuti di un modulo, per un certo periodo di tempo (giorni, in alcuni casi) dopo il download del modulo:
- La piattaforma non può applicare nuove voci manifest introdotte dal modulo.
- La piattaforma non può accedere alle risorse del modulo per i componenti dell'interfaccia utente di sistema, come le notifiche. Se hai bisogno di utilizzare queste risorse immediatamente, valuta la possibilità di includerle nel modulo di base dell'app.
Abilita SplitCompat
Affinché un'app possa accedere al codice e alle risorse di un modulo scaricato, devi abilitare SplitCompat utilizzando solo uno dei metodi descritti nelle sezioni seguenti.
Dopo aver attivato SplitCompat per la tua app, devi abilitare anche SplitCompat per ogni attività nei moduli delle funzionalità a cui vuoi che la tua app abbia accesso.
Dichiara SplitCompatApplication nel manifest
Il modo più semplice per abilitare SplitCompat è dichiarare SplitCompatApplication
come la sottoclasse Application
nel
file manifest della tua app, come mostrato di seguito:
<application
...
android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
</application>
Dopo aver installato l'app su un dispositivo, puoi accedere automaticamente al codice e alle risorse dai moduli delle funzionalità scaricati.
Richiama SplitCompat in fase di runtime
Puoi anche abilitare SplitCompat in attività o servizi specifici in fase di runtime.
È necessario attivare SplitCompat in questo modo per avviare le attività incluse nei moduli delle funzionalità. Per farlo, sostituisci attachBaseContext
come mostrato di seguito.
Se hai una classe Application personalizzata,
prolunga invece
SplitCompatApplication
per abilitare SplitCompat per la tua app, come mostrato di seguito:
Kotlin
class MyApplication : SplitCompatApplication() { ... }
Java
public class MyApplication extends SplitCompatApplication { ... }
SplitCompatApplication
sostituisce semplicemente ContextWrapper.attachBaseContext()
per includere SplitCompat.install(Context applicationContext)
. Se non vuoi
che la tua classe Application
estenda SplitCompatApplication
, puoi eseguire l'override del metodo attachBaseContext()
manualmente, come segue:
Kotlin
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) // Emulates installation of future on demand modules using SplitCompat. SplitCompat.install(this) }
Java
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // Emulates installation of future on demand modules using SplitCompat. SplitCompat.install(this); }
Se il modulo on demand è compatibile con le app istantanee e le app installate, puoi richiamare SplitCompat in modo condizionale, come segue:
Kotlin
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) if (!InstantApps.isInstantApp(this)) { SplitCompat.install(this) } }
Java
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); if (!InstantApps.isInstantApp(this)) { SplitCompat.install(this); } }
Abilita SplitCompat per le attività dei moduli
Dopo aver attivato SplitCompat per la tua app di base, devi abilitare SplitCompat
per ogni attività scaricata dall'app in un modulo delle funzionalità. Per farlo, utilizza il metodo SplitCompat.installActivity()
come segue:
Kotlin
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) // Emulates installation of on demand modules using SplitCompat. SplitCompat.installActivity(this) }
Java
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // Emulates installation of on demand modules using SplitCompat. SplitCompat.installActivity(this); }
Accedi ai componenti definiti nei moduli delle funzionalità
Avviare un'attività definita in un modulo delle funzionalità
Puoi avviare le attività definite nei moduli delle funzionalità utilizzando startActivity()
dopo aver abilitato SplitCompat.
Kotlin
startActivity(Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...))
Java
startActivity(new Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...));
Il primo parametro di setClassName
è il nome del pacchetto dell'app e il secondo parametro è il nome completo della classe dell'attività.
Quando è presente un'attività in un modulo di funzionalità che hai scaricato on demand, devi abilitare SplitCompat nell'attività.
Avviare un servizio definito in un modulo delle funzionalità
Puoi avviare i servizi definiti nei moduli delle funzionalità utilizzando startService()
dopo aver abilitato SplitCompat.
Kotlin
startService(Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...))
Java
startService(new Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...));
Esportare un componente definito in un modulo delle funzionalità
Non includere i componenti Android esportati all'interno di moduli facoltativi.
Il sistema di build unisce le voci manifest per tutti i moduli nel modulo di base. Se un modulo facoltativo conteneva un componente esportato, questo sarà accessibile anche prima dell'installazione del modulo e potrebbe causare un arresto anomalo a causa della mancanza di codice quando viene richiamato da un'altra app.
Questo non è un problema per i componenti interni, poiché sono accessibili solo dall'app, quindi l'app può verificare che il modulo sia installato prima di accedere al componente.
Se ti serve un componente esportato e vuoi che i suoi contenuti siano in un modulo facoltativo, valuta la possibilità di implementare un pattern proxy.
Per farlo, aggiungi un componente proxy esportato nella base. Se si accede, il componente proxy può verificare la presenza del modulo che contiene i contenuti. Se il modulo è presente, il componente proxy può avviare il componente interno dal modulo tramite un Intent
, relazionando l'intent dall'app del chiamante. Se il modulo non è presente, il componente può scaricarlo o restituire un messaggio di errore appropriato all'app chiamante.
Accedi a codice e risorse dai moduli installati
Se abiliti SplitCompat per il contesto dell'applicazione di base e le attività nel modulo delle funzionalità, puoi utilizzare il codice e le risorse di un modulo di funzionalità come se facessero parte dell'APK di base, dopo l'installazione del modulo facoltativo.
Codice di accesso da un altro modulo
Accedi al codice di base da un modulo
Il codice all'interno del modulo di base può essere utilizzato direttamente da altri moduli. Non devi fare nulla di speciale; importa e utilizza i corsi di cui hai bisogno.
Accedi al codice del modulo da un altro modulo
Un oggetto o una classe all'interno di un modulo non è accessibile in modo statico da un altro modulo, ma è possibile accedervi indirettamente tramite la riflessione.
Devi diffidare della frequenza con cui ciò accade, per via dei costi della riflessione in termini di prestazioni. Per casi d'uso complessi, utilizza framework di inserimento delle dipendenze come Dagger 2 per garantire un'unica chiamata di riflessione per tutta la durata dell'applicazione.
Per semplificare le interazioni con l'oggetto dopo la creazione di un'istanza, consigliamo di definire un'interfaccia nel modulo di base e la sua implementazione nel modulo delle funzionalità. Ad esempio:
Kotlin
// In the base module interface MyInterface { fun hello(): String } // In the feature module object MyInterfaceImpl : MyInterface { override fun hello() = "Hello" } // In the base module, where we want to access the feature module code val stringFromModule = (Class.forName("com.package.module.MyInterfaceImpl") .kotlin.objectInstance as MyInterface).hello();
Java
// In the base module public interface MyInterface { String hello(); } // In the feature module public class MyInterfaceImpl implements MyInterface { @Override public String hello() { return "Hello"; } } // In the base module, where we want to access the feature module code String stringFromModule = ((MyInterface) Class.forName("com.package.module.MyInterfaceImpl").getConstructor().newInstance()).hello();
Accesso a risorse e asset da un modulo diverso
Una volta installato un modulo, puoi accedere alle risorse e agli asset al suo interno nel modo standard, tenendo presenti due avvertenze:
- Se accedi a una risorsa da un modulo diverso, il modulo non avrà accesso all'identificatore della risorsa, sebbene alla risorsa sia comunque possibile accedervi per nome. Nota che il pacchetto da utilizzare per fare riferimento alla risorsa è il pacchetto del modulo in cui è definita la risorsa.
- Se vuoi accedere ad asset o risorse esistenti in un modulo appena installato da un altro modulo installato della tua app, devi utilizzare il contesto dell'applicazione. Il contesto del componente che sta tentando di accedere alle risorse non sarà ancora aggiornato. In alternativa, puoi ricreare il componente (ad esempio chiamando Activity.recreate()) o reinstallare SplitCompat su questo componente dopo l'installazione del modulo della funzionalità.
Caricare il codice nativo in un'app utilizzando la distribuzione on demand
Ti consigliamo di utilizzare ReLinker per caricare tutte le librerie native quando utilizzi la distribuzione on demand di moduli di funzionalità. ReLinker corregge un problema di caricamento delle librerie native dopo l'installazione di un modulo delle funzionalità. Puoi scoprire di più su ReLinker nei suggerimenti per JNI per Android.
Carica il codice nativo da un modulo facoltativo
Una volta installata una suddivisione, consigliamo di caricare il codice nativo tramite ReLinker. Per le app istantanee, devi utilizzare questo metodo speciale.
Se utilizzi System.loadLibrary()
per caricare il codice nativo e la libreria nativa ha una dipendenza da un'altra libreria nel modulo, devi prima caricare manualmente l'altra libreria.
Se utilizzi ReLinker, l'operazione equivalente è
Relinker.recursively().loadLibrary()
.
Se utilizzi dlopen()
nel codice nativo per caricare una libreria definita in un
modulo facoltativo, non funzionerà con i percorsi relativi della libreria.
La soluzione migliore è recuperare il percorso assoluto della libreria dal codice Java tramite ClassLoader.findLibrary()
e utilizzarlo nella chiamata dlopen()
.
Esegui questa operazione prima di inserire il codice nativo o utilizza una chiamata JNI dal codice nativo in Java.
Accesso alle app istantanee Android installate
Dopo che un modulo dell'app istantanea Android segnala come INSTALLED
, puoi accedere al relativo codice e alle relative risorse utilizzando il Contesto dell'app aggiornata. Un
contesto creato dalla tua app prima di installare un modulo (ad esempio, uno che è già archiviato in una variabile) non include i contenuti del nuovo
modulo. Ma un nuovo contesto sì, puoi ottenere questo risultato, ad esempio, utilizzando createPackageContext
.
Kotlin
// Generate a new context as soon as a request for a new module // reports as INSTALLED. override fun onStateUpdate(state: SplitInstallSessionState ) { if (state.sessionId() == mySessionId) { when (state.status()) { ... SplitInstallSessionStatus.INSTALLED -> { val newContext = context.createPackageContext(context.packageName, 0) // If you use AssetManager to access your app’s raw asset files, you’ll need // to generate a new AssetManager instance from the updated context. val am = newContext.assets } } } }
Java
// Generate a new context as soon as a request for a new module // reports as INSTALLED. @Override public void onStateUpdate(SplitInstallSessionState state) { if (state.sessionId() == mySessionId) { switch (state.status()) { ... case SplitInstallSessionStatus.INSTALLED: Context newContext = context.createPackageContext(context.getPackageName(), 0); // If you use AssetManager to access your app’s raw asset files, you’ll need // to generate a new AssetManager instance from the updated context. AssetManager am = newContext.getAssets(); } } }
App istantanee Android su Android 8.0 e versioni successive
Quando richiedi un modulo on demand per un'app istantanea Android su Android 8.0
(livello API 26) e versioni successive, dopo che una richiesta di installazione segnala come INSTALLED
, devi aggiornare l'app con il contesto del nuovo modulo tramite una chiamata a
SplitInstallHelper.updateAppInfo(Context context)
.
In caso contrario, l'app non è ancora a conoscenza
del codice e delle risorse del modulo. Dopo aver aggiornato i metadati dell'app, devi caricare i contenuti del modulo durante il successivo evento del thread principale richiamando un nuovo Handler
, come mostrato di seguito:
Kotlin
override fun onStateUpdate(state: SplitInstallSessionState ) { if (state.sessionId() == mySessionId) { when (state.status()) { ... SplitInstallSessionStatus.INSTALLED -> { // You need to perform the following only for Android Instant Apps // running on Android 8.0 (API level 26) and higher. if (BuildCompat.isAtLeastO()) { // Updates the app’s context with the code and resources of the // installed module. SplitInstallHelper.updateAppInfo(context) Handler().post { // Loads contents from the module using AssetManager val am = context.assets ... } } } } } }
Java
@Override public void onStateUpdate(SplitInstallSessionState state) { if (state.sessionId() == mySessionId) { switch (state.status()) { ... case SplitInstallSessionStatus.INSTALLED: // You need to perform the following only for Android Instant Apps // running on Android 8.0 (API level 26) and higher. if (BuildCompat.isAtLeastO()) { // Updates the app’s context with the code and resources of the // installed module. SplitInstallHelper.updateAppInfo(context); new Handler().post(new Runnable() { @Override public void run() { // Loads contents from the module using AssetManager AssetManager am = context.getAssets(); ... } }); } } } }
Carica le librerie C/C++
Se vuoi caricare librerie C/C++ da un modulo che il dispositivo ha già
scaricato in un'app istantanea, utilizza
SplitInstallHelper.loadLibrary(Context context, String libName)
,
come mostrato di seguito:
Kotlin
override fun onStateUpdate(state: SplitInstallSessionState) { if (state.sessionId() == mySessionId) { when (state.status()) { SplitInstallSessionStatus.INSTALLED -> { // Updates the app’s context as soon as a module is installed. val newContext = context.createPackageContext(context.packageName, 0) // To load C/C++ libraries from an installed module, use the following API // instead of System.load(). SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”) ... } } } }
Java
public void onStateUpdate(SplitInstallSessionState state) { if (state.sessionId() == mySessionId) { switch (state.status()) { case SplitInstallSessionStatus.INSTALLED: // Updates the app’s context as soon as a module is installed. Context newContext = context.createPackageContext(context.getPackageName(), 0); // To load C/C++ libraries from an installed module, use the following API // instead of System.load(). SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”); ... } } }
Limitazioni note
- Non è possibile utilizzare Android WebView in un'attività che accede a risorse o asset da un modulo facoltativo. Ciò è dovuto a un'incompatibilità tra WebView e SplitCompat su API Android 28 e livelli precedenti.
- Non puoi memorizzare nella cache gli oggetti Android
ApplicationInfo
, i relativi contenuti o gli oggetti che li contengono all'interno dell'app. Devi sempre recuperare questi oggetti in base alle esigenze dal contesto di un'app. La memorizzazione nella cache di questi oggetti potrebbe causare l'arresto anomalo dell'app durante l'installazione di un modulo di funzionalità.
Gestisci i moduli installati
Per controllare quali moduli delle funzionalità sono attualmente installati sul dispositivo,
puoi chiamare
SplitInstallManager.getInstalledModules()
,
che restituisce un Set<String>
dei nomi dei moduli installati, come mostrato di seguito.
Kotlin
val installedModules: Set<String> = splitInstallManager.installedModules
Java
Set<String> installedModules = splitInstallManager.getInstalledModules();
Disinstalla moduli
Puoi richiedere al dispositivo di disinstallare i moduli richiamando
SplitInstallManager.deferredUninstall(List<String> moduleNames)
,
come mostrato di seguito.
Kotlin
// Specifies two feature modules for deferred uninstall. splitInstallManager.deferredUninstall(listOf("pictureMessages", "promotionalFilters"))
Java
// Specifies two feature modules for deferred uninstall. splitInstallManager.deferredUninstall(Arrays.asList("pictureMessages", "promotionalFilters"));
Le disinstallazioni dei moduli non avvengono immediatamente. In altre parole, il dispositivo le disinstalla in background per risparmiare spazio di archiviazione.
Puoi confermare che il dispositivo abbia eliminato un modulo richiamando SplitInstallManager.getInstalledModules()
e ispezionando il risultato, come descritto nella sezione precedente.
Scarica risorse linguistiche aggiuntive
Con gli app bundle, i dispositivi scaricano solo il codice e le risorse necessari per eseguire l'app. Pertanto, per le risorse della lingua, il dispositivo di un utente scarica solo le risorse della lingua dell'app che corrispondono a una o più lingue attualmente selezionate nelle impostazioni del dispositivo.
Se vuoi che la tua app abbia accesso a risorse linguistiche aggiuntive, ad esempio per implementare un selettore lingua in-app, puoi usare la Raccolta di funzionalità di Play per scaricarla on demand. La procedura è simile a quella per il download di un modulo delle funzionalità, come mostrato di seguito.
Kotlin
// Captures the user’s preferred language and persists it // through the app’s SharedPreferences. sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply() ... // Creates a request to download and install additional language resources. val request = SplitInstallRequest.newBuilder() // Uses the addLanguage() method to include French language resources in the request. // Note that country codes are ignored. That is, if your app // includes resources for “fr-FR” and “fr-CA”, resources for both // country codes are downloaded when requesting resources for "fr". .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))) .build() // Submits the request to install the additional language resources. splitInstallManager.startInstall(request)
Java
// Captures the user’s preferred language and persists it // through the app’s SharedPreferences. sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply(); ... // Creates a request to download and install additional language resources. SplitInstallRequest request = SplitInstallRequest.newBuilder() // Uses the addLanguage() method to include French language resources in the request. // Note that country codes are ignored. That is, if your app // includes resources for “fr-FR” and “fr-CA”, resources for both // country codes are downloaded when requesting resources for "fr". .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))) .build(); // Submits the request to install the additional language resources. splitInstallManager.startInstall(request);
La richiesta viene gestita come se fosse una richiesta per un modulo delle funzionalità. Ciò significa che puoi monitorare lo stato della richiesta come faresti normalmente.
Se la tua app non richiede immediatamente le risorse di lingua aggiuntive, puoi posticipare l'installazione quando l'app è in background, come mostrato di seguito.
Kotlin
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
Java
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
Accesso alle risorse linguistiche scaricate
Per ottenere l'accesso alle risorse linguistiche scaricate, la tua app deve eseguire il
metodo SplitCompat.installActivity()
nel metodo attachBaseContext()
di ogni attività che richiede l'accesso a queste risorse, come mostrato di seguito.
Kotlin
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) SplitCompat.installActivity(this) }
Java
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); SplitCompat.installActivity(this); }
Per ogni attività per cui vuoi utilizzare risorse linguistiche che l'app ha scaricato,
aggiorna il contesto di base e imposta una nuova lingua tramite
Configuration
:
Kotlin
override fun attachBaseContext(base: Context) { val configuration = Configuration() configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))) val context = base.createConfigurationContext(configuration) super.attachBaseContext(context) SplitCompat.install(this) }
Java
@Override protected void attachBaseContext(Context base) { Configuration configuration = new Configuration(); configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))); Context context = base.createConfigurationContext(configuration); super.attachBaseContext(context); SplitCompat.install(this); }
Affinché queste modifiche abbiano effetto, devi ricreare l'attività
dopo che la nuova lingua è stata installata ed è pronta per essere utilizzata. Puoi usare il
metodo Activity#recreate()
.
Kotlin
when (state.status()) { SplitInstallSessionStatus.INSTALLED -> { // Recreates the activity to load resources for the new language // preference. activity.recreate() } ... }
Java
switch (state.status()) { case SplitInstallSessionStatus.INSTALLED: // Recreates the activity to load resources for the new language // preference. activity.recreate(); ... }
Disinstallare le risorse linguistiche aggiuntive
Come per i moduli delle funzionalità, puoi disinstallare risorse aggiuntive in qualsiasi momento. Prima di richiedere una disinstallazione, ti consigliamo di verificare le lingue attualmente installate, come descritto di seguito.
Kotlin
val installedLanguages: Set<String> = splitInstallManager.installedLanguages
Java
Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();
Puoi quindi decidere quali lingue disinstallare utilizzando il metodo deferredLanguageUninstall()
, come mostrato di seguito.
Kotlin
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
Java
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
Installazioni di moduli di test a livello locale
La libreria Play Feature Delivery ti consente di testare localmente la capacità della tua app di effettuare le seguenti operazioni, senza connetterti al Play Store:
- Richiedi e monitora le installazioni di moduli.
- Gestire gli errori di installazione.
- Utilizza
SplitCompat
per accedere ai moduli.
In questa pagina viene descritto come eseguire il deployment degli APK divisi dell'app sul dispositivo di test in modo che Play Feature Delivery utilizzi automaticamente questi APK per simulare la richiesta, il download e l'installazione di moduli dal Play Store.
Anche se non è necessario apportare modifiche alla logica dell'app, devi soddisfare i seguenti requisiti:
- Scarica e installa l'ultima versione di
bundletool
. Devi averebundletool
per creare un nuovo insieme di APK installabili dal bundle della tua app.
Crea un insieme di APK
Se non l'hai ancora fatto, crea gli APK divisi per la tua app, come segue:
- Crea un app bundle per la tua app utilizzando uno dei seguenti metodi:
- Usa Android Studio e il plug-in Android per Gradle per creare e firmare un Android App Bundle.
- Crea l'app bundle dalla riga di comando.
Utilizza
bundletool
per generare un insieme di APK per tutte le configurazioni del dispositivo con il seguente comando:bundletool build-apks --local-testing --bundle my_app.aab --output my_app.apks
Il flag --local-testing
include metadati nei file manifest degli APK che
indicano alla libreria Play Feature Delivery di usare gli APK divisi locali per testare
l'installazione dei moduli delle funzionalità, senza connettersi al Play Store.
Esegui il deployment dell'app sul dispositivo
Dopo aver creato un insieme di APK utilizzando il flag --local-testing
,
utilizza bundletool
per installare la versione di base dell'app e trasferire altri
APK nello spazio di archiviazione locale del dispositivo. Puoi eseguire entrambe le azioni con il seguente comando:
bundletool install-apks --apks my_app.apks
Ora, quando avvii l'app e completi il flusso utente per scaricare e installare
un modulo di funzionalità, la libreria di Google Play Feature Delivery utilizza gli APK che bundletool
ha trasferito nello spazio di archiviazione locale del dispositivo.
Simula un errore di rete
Per simulare le installazioni di moduli dal Play Store, la libreria Play Feature Delivery utilizza un'alternativa a SplitInstallManager
, chiamata FakeSplitInstallManager
, per richiedere il modulo. Quando usi bundletool
con il flag --local-testing
per creare un insieme di APK e implementarli sul dispositivo di test,
include i metadati che indicano alla libreria Play Feature Delivery di cambiare automaticamente
le chiamate API della tua app in modo che richiamino FakeSplitInstallManager
anziché
SplitInstallManager
.
FakeSplitInstallManager
include un flag booleano che puoi attivare per
simulare un errore di rete la prossima volta che la tua app richiede l'installazione di un modulo. Per accedere a FakeSplitInstallManager
nei test, puoi ottenere un'istanza utilizzando FakeSplitInstallManagerFactory
, come mostrato di seguito:
Kotlin
// Creates an instance of FakeSplitInstallManager with the app's context. val fakeSplitInstallManager = FakeSplitInstallManagerFactory.create(context) // Tells Play Feature Delivery Library to force the next module request to // result in a network error. fakeSplitInstallManager.setShouldNetworkError(true)
Java
// Creates an instance of FakeSplitInstallManager with the app's context. FakeSplitInstallManager fakeSplitInstallManager = FakeSplitInstallManagerFactory.create(context); // Tells Play Feature Delivery Library to force the next module request to // result in a network error. fakeSplitInstallManager.setShouldNetworkError(true);