Configura la pubblicazione on demand

I moduli delle funzionalità ti consentono di separare determinate funzionalità e risorse dal modulo di base dell'app e includile nell'app bundle. Tramite Play Feature Delivery, gli utenti possono, ad esempio, in un secondo momento scaricarli e installarli componenti on demand dopo che hanno già installato l'APK di base della tua app.

Ad esempio, prendi in considerazione un'app di messaggistica che include funzionalità per acquisire e inviare messaggi con immagini, ma solo una piccola percentuale di utenti inviare messaggi con immagini. Potrebbe essere opportuno includere messaggi con immagini sotto forma di modulo delle funzionalità scaricabile. In questo modo, il download iniziale dell'app più piccoli per tutti gli utenti e solo quelli che inviano messaggi con immagini devono scaricare il componente aggiuntivo.

Tieni presente che questo tipo di modularizzazione richiede più impegno e possibilmente eseguire il refactoring del codice esistente della tua app, quindi valuta attentamente a quale dei tuoi le funzionalità dell'app trarrebbero il massimo vantaggio dalla disponibilità per gli utenti on demand. Per comprendere meglio le linee guida e i casi d'uso ottimali per le funzionalità on demand, leggi le best practice relative all'esperienza utente per la distribuzione on demand.

Se vuoi modularizzare gradualmente le funzionalità dell'app nel tempo, senza abilitando opzioni di pubblicazione avanzate, come la pubblicazione on demand, configurare la consegna al momento dell'installazione.

Questa pagina ti aiuta ad aggiungere un modulo di funzionalità al progetto dell'app e per la distribuzione on demand. Prima di iniziare, assicurati di avere Con Android Studio 3.5 o versioni successive e il plug-in Android Gradle 3.5.0 o superiore.

Configura un nuovo modulo per la distribuzione on demand

Il modo più semplice per creare un nuovo modulo di funzionalità è usare Android Studio 3.5 o versioni successive. Poiché i moduli delle caratteristiche hanno un dipendenza intrinseca dal modulo dell'app di base, puoi aggiungerle solo alle applicazioni di Google Cloud.

Per aggiungere un modulo di funzionalità al progetto della tua app utilizzando Android Studio: procedi nel seguente modo:

  1. Se non l'hai ancora fatto, apri il progetto dell'app nell'IDE.
  2. Seleziona File > Nuovo > Nuovo modulo dalla barra dei menu.
  3. Nella finestra di dialogo Crea nuovo modulo, seleziona Modulo di funzionalità dinamiche e fai clic su Avanti.
  4. Nella sezione Configura il nuovo modulo, completa il seguenti:
      .
    1. Seleziona il modulo di applicazione di base per il progetto della tua app da dal menu a discesa.
    2. Specifica un Nome modulo. L'IDE utilizza questo nome per identificare come sottoprogetto Gradle nel tuo File delle impostazioni di Gradle. Quando creare l'app bundle, Gradle usa l'ultimo elemento del sottoprogetto per inserire l'attributo <manifest split> in manifest del modulo delle funzionalità.
    3. Specifica il nome del pacchetto del modulo. Per impostazione predefinita, Android Studio suggerisce un nome pacchetto che combina il nome del pacchetto modulo di base e il nome del modulo che hai specificato nel passaggio precedente.
    4. Seleziona il livello API minimo che il modulo deve supportare. Questo valore deve corrispondere a quello del modulo di base.
  5. Fai clic su Avanti.
  6. Nella sezione Opzioni di download del modulo, completa quanto segue:

    1. Specifica il titolo del modulo utilizzando fino a 50 caratteri. La piattaforma utilizza questo titolo per identificare il modulo per gli utenti quando, ad esempio, confermando se l'utente vuole scaricare il modulo. Per questo motivo, il modulo di base dell'app deve includere il titolo del modulo come stringa di risorsa, che hai possono tradurre. Quando crei il modulo usando Android Studio, l'IDE aggiunge la risorsa di stringa al modulo di base per te e inserisce la seguente nel manifest del modulo delle funzionalità:

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. Nel menu a discesa in Inclusione al momento dell'installazione, seleziona Non includi il modulo al momento dell'installazione. Android Studio inserisce il nel file manifest del modulo per riflettere la tua scelta:

      <dist:module ... >
        <dist:delivery>
            <dist:on-demand/>
        </dist:delivery>
      </dist:module>
      
    3. Seleziona la casella accanto a Fondazione se vuoi che questo modulo sia disponibile ai dispositivi con Android 4.4 (livello API 20) e versioni precedenti e inclusi APK multipli. Ciò significa che puoi abilitare il comportamento on demand per questo modulo e disattiva la fusione per ometterla dai dispositivi che non supportano scaricare e installare APK divisi. Android Studio inserisce il nel file manifest del modulo per riflettere la tua scelta:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. 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 in modo simile 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 iniziare, devi aggiungi 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 tramite SplitInstallManager . Quando effettui una richiesta, la tua app deve specificare il nome del modulo come definito Elemento split nel manifest del modulo target. Quando crea un modulo di funzionalità utilizzando Android Studio, il sistema di compilazione utilizza il nome del modulo che fornisci per inserire questa proprietà nel manifest del modulo al momento della compilazione. Per ulteriori informazioni, leggi le informazioni manifest dei moduli delle funzionalità.

Ad esempio, considera un'app che ha un modulo on demand per acquisire e inviare messaggi con immagini usando la fotocamera del dispositivo e questo modulo on demand specifica split="pictureMessages" nel file manifest. La il seguente esempio utilizza SplitInstallManager per richiedere 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 un la strategia "fire-and-forget". Ciò significa che invia la richiesta di download modulo alla piattaforma, ma non monitora se l'installazione riuscito. Per proseguire il percorso dell'utente dopo installazione o di gestire correttamente gli errori, assicurati di monitorare la richiesta .

Nota: è consentito richiedere un modulo delle funzionalità già installato sul dispositivo. L'API considera immediatamente la richiesta come completata se rileva che il modulo è già installato. Inoltre, una volta installato 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, consulta Gestire gli aggiornamenti delle app.

Per avere accesso al codice e alle risorse del modulo, la tua app deve Attivare SplitCompat. Tieni presente che SplitCompat non necessaria per le app istantanee Android.

Rimanda l'installazione di moduli on demand

Se non hai bisogno dell'app per scaricare e installare immediatamente un'app on demand puoi posticipare l'installazione quando l'app è in background. Per Ad esempio, se vuoi precaricare del materiale promozionale per un lancio successivo di la tua app.

Puoi specificare un modulo da scaricare in un secondo momento utilizzando il deferredInstall() come mostrato di seguito. E, a differenza di SplitInstallManager.startInstall(), non è necessario che la tua app sia in primo piano per avviare una richiesta di dell'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 di installazioni differite sono eseguite secondo il criterio del "best effort" e non puoi monitorarne progressi. Quindi, prima di tentare di accedere a un modulo che hai specificato per Differito è necessario installare verifica che il modulo sia stato installato. Se il modulo sia disponibile immediatamente, usa SplitInstallManager.startInstall() per richiederlo, come mostrato nell'articolo precedente .

Monitora lo stato della richiesta

Per poter aggiornare una barra di avanzamento, attiva un intent dopo installare l'installazione o gestire in modo controllato un errore della richiesta, devi rimanere in ascolto gli aggiornamenti di stato dall'attività SplitInstallManager.startInstall() asincrona. Per poter iniziare a ricevere aggiornamenti per la tua richiesta di installazione, registra un listener e ottenere 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 di un'app non sempre va a buon fine. La mancata installazione può essere dovuta problemi quali spazio di archiviazione sul dispositivo in esaurimento, nessuna connettività di rete o mancata connessione da parte dell'utente eseguito l'accesso al Google Play Store. Per suggerimenti su come gestire queste situazioni con eleganza dal punto di vista dell'utente, dai un'occhiata Linee guida per l'esperienza utente per la distribuzione 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é ne esiste almeno una richiesta in fase di download. Controlla se ci sono richieste ancora in fase di download, come mostrato nell'esempio precedente.
MODULE_NON DISPONIBILE Google Play non riesce a trovare il modulo richiesto in base sulla versione attualmente installata dell'app, del dispositivo e di Google Play dell'utente . Se l'utente non ha accesso al modulo, avvisalo.
RICHIESTA_NON_VALIDA Google Play ha ricevuto la richiesta, ma la richiesta non è valido. Verifica che le informazioni incluse nella richiesta sia completa e accurata.
SESSIONE_NON_TROVATA Impossibile trovare una sessione per un determinato ID sessione. Se stai cercando di monitorare lo stato di una richiesta in base all'ID sessione, accertati 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 riesce a scaricare e installare on demand. Per i dispositivi con Android 4.4 (livello API 20) o versioni precedenti, includere moduli delle funzionalità al momento dell'installazione utilizzando Proprietà del file manifest dist:fusing. Per saperne di più, leggi le informazioni 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 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à stati richieste ma non ancora installate. Crea una nuova richiesta che non includa i moduli l'app ha già richiesto o attendi tutti i moduli attualmente richiesti per completare l'installazione prima di riprovare a inviare la richiesta.

Ricorda che la richiesta di un modulo che è già stata non risolve un errore.

SERVIZIO_DIED Il servizio responsabile della gestione della richiesta è terminato. Riprova a inviare la richiesta.

Il tuo SplitInstallStateUpdatedListener riceve un SplitInstallSessionState con questo codice di errore, stato FAILED e ID sessione -1.

ARCHIVIAZIONE_INSUFFICIENTE Lo spazio di archiviazione sul dispositivo non è sufficiente per installare la funzionalità in maggior dettaglio più avanti in questo modulo. Comunica all'utente che non dispone di spazio di archiviazione sufficiente per eseguire l'installazione funzionalità.
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR Impossibile caricare il modulo delle funzionalità da SplitCompat. Questi errori dovrebbero risolversi automaticamente dopo la successiva app riavvia.
PLAY_STORE_NOT_FOUND L'app Play Store non è installata sul dispositivo. Comunica all'utente che per scaricare l'app è necessaria l'app Play Store funzionalità.
APP_NON_POSITIVA L'app non è stata installata da Google Play e la funzionalità non può essere scaricato. 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 il necessario conferma dell'utente.
INTERNAL_ERROR 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 che offra due opzioni per l'utente: Prova ancora (che tenta di inviare nuovamente la richiesta) e Annulla (che abbandona il richiesta). Per ulteriore assistenza, fornisci anche il link alla 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, usa StateUpdatedListener.onStateUpdate() per gestire le modifiche dello 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. Inizializzare 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. Di solito questo stato si verifica se l'app non è stata installata tramite su Google Play. Chiedere all'utente di confermare il download della funzionalità tramite Google Play. Per saperne 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 SplitInstallSessionState.bytesDownloaded() e SplitInstallSessionState.totalBytesToDownload() per aggiornare l'interfaccia utente (vedi l'esempio di codice sopra questa tabella).
SCARICATO Il dispositivo ha scaricato il modulo, ma l'installazione non è ancora iniziata. Le app devono abilitare SplitCompat per avere accesso ai moduli scaricati ed evitare di vedere questo stato. È necessaria per accedere al codice del modulo della funzionalità e Google Cloud.
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 in esecuzione su Android 8.0 (livello API 26) o successiva, devi usare splitInstallHelper per aggiornare i componenti dell'app con il nuovo modulo.

OPERAZIONE NON RIUSCITA La richiesta non è andata a buon fine prima che il modulo fosse installato sul dispositivo. Chiedi all'utente di riprovare la richiesta o di annullarla.
ANNULLAMENTO Il dispositivo sta per annullare la richiesta. Per saperne 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 un richiesta di download. Ad esempio, se la tua app non è stata installata da Google. Google Play o se stai tentando di eseguire un download di grandi dimensioni tramite dati mobili. In questi casi, lo stato dei report sulle richieste REQUIRES_USER_CONFIRMATION e la tua app deve ottenere la conferma dell'utente affinché il dispositivo possa scaricare e installare i moduli nella richiesta. Per ricevere conferma, l'app deve all'utente:

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 di risultati di attività usando la ActivityResultContracts.StartIntentSenderForResult contratto. 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 prosegue.
  • 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 ignorare il parametro 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, la tua app deve attivare Libreria SplitCompat sia per la tua app sia per ogni attività nei moduli delle funzionalità della tua app per i download.

Tuttavia, tieni presente che la piattaforma presenta quanto segue: limitazioni all'accesso ai contenuti di un modulo, per un certo periodo di tempo (giorni, casi) dopo aver scaricato il 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 immediatamente queste risorse, incluse le risorse nel modulo di base dell'app.

Abilita SplitCompat

Per consentire alla tua app di accedere al codice e alle risorse di un modulo scaricato: devi attivare SplitCompat utilizzando solo uno dei metodi descritti in le sezioni seguenti.

Dopo aver attivato SplitCompat per la tua app, devi anche abilitare 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 sottoclasse Application in il file manifest dell'app, come mostrato di seguito:

<application
    ...
    android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
</application>

Una volta installata l'app su un dispositivo, puoi accedere al codice e alle risorse da scaricati automaticamente i moduli delle funzionalità.

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 in moduli delle funzionalità. Per farlo, sostituisci attachBaseContext come mostrato di seguito.

Se hai una classe Application personalizzata, estenderla SplitCompatApplication: per attivare 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). In caso contrario vuoi che il tuo corso Application estendere SplitCompatApplication, puoi eseguire l'override di 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 attivare SplitCompat per ogni attività scaricata dalla tua app in un modulo di 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 attività definite nei moduli delle funzionalità utilizzando startActivity() dopo l'attivazione di 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 l'attivazione di 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 compilazione unisce le voci manifest per tutti i moduli nel modulo di base. se un modulo facoltativo contenesse un componente esportato, questo sarebbe accessibile anche prima dell'installazione del modulo e può causare un arresto anomalo a causa di codice mancante quando richiamati da un'altra app.

Questo non è un problema per i componenti interni; a cui si accede solo dall'app, in modo che possa verifica che il modulo sia installato prima di accedere del componente.

Se hai bisogno di un componente esportato e vuoi che i suoi contenuti siano in un componente facoltativo modulo, considera l'implementazione di un pattern proxy. Puoi farlo aggiungendo alla base un componente esportato del proxy. quando viene eseguito l'accesso, il componente proxy può verificare la presenza del modulo che include i contenuti. Se il modulo è presente, il proxy può avviare il componente interno dal modulo tramite un Intent, l'intent da parte dell'app chiamante. Se il modulo non è presente, può scaricare il modulo o restituire un messaggio di errore appropriato al app chiamante.

Accedi a codice e risorse dai moduli installati

Se attivi SplitCompat per la tua base contesto dell'applicazione e le attività nel modulo delle funzionalità, puoi utilizzare codice e risorse di un modulo delle funzionalità come se fosse parte di un APK di base, una volta installato il 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 direttamente dal modulo, ma vi si può accedere indirettamente, usando la riflessione.

Devi diffidare della frequenza con cui ciò accade, per via dei costi del rendimento di riflessione. Per casi d'uso complessi, usa framework di inserimento delle dipendenze come Dagger 2 per garantire una singola chiamata di riflessione per per tutta la durata dell'applicazione.

Per semplificare le interazioni con l'oggetto dopo la creazione di un'istanza, è necessario è consigliabile definire un'interfaccia nel modulo di base e la sua implementazione il 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 all'interno del modulo in modo standard, con due avvertenze:

  • Se accedi a una risorsa da un modulo diverso, il modulo non hanno accesso all'identificatore della risorsa, sebbene la risorsa possa a cui si accede per nome. Tieni presente che il pacchetto da usare per fare riferimento alla risorsa è del modulo in cui è definita la risorsa.
  • Se vuoi accedere ad asset o risorse esistenti in un ambiente da un modulo installato diverso della tua app, devi farlo utilizzando contesto dell'applicazione. Il contesto del componente che sta tentando di accedere alle risorse non sarà ancora essere aggiornate. In alternativa, puoi ricrearlo (ad esempio chiamando Activity.recreate()) oppure reinstallare SplitCompat su questo dispositivo dopo il modulo delle funzionalità dell'installazione.

Caricare il codice nativo in un'app utilizzando la distribuzione on demand

Ti consigliamo di utilizzare ReLinker per caricare tutti le tue 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 nel Suggerimenti 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 libreria ha una dipendenza da un'altra libreria nel modulo, devi manualmente per caricare prima 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 percorsi relativi della libreria. La soluzione migliore è recuperare il percorso assoluto della libreria dal codice Java. tramite ClassLoader.findLibrary(), per poi usarlo nella tua chiamata con dlopen(). Esegui questa operazione prima di inserire il codice nativo o utilizza una chiamata JNI dal tuo codice nativo in Java.

Accesso alle app istantanee Android installate

Dopo che un modulo delle app istantanee Android segnala come INSTALLED, puoi accedere ai suoi con un'app aggiornata Contesto: R contesto creato dalla tua app prima di installare un modulo (ad esempio, una già memorizzato in una variabile) non include i contenuti dei nuovi in maggior dettaglio più avanti in questo modulo. Ma un nuovo contesto sì, questo si può ottenere, ad esempio, usando 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 viene richiesto un modulo on demand per un'app istantanea Android su Android 8.0 (livello API 26) e superiore, dopo che una richiesta di installazione segnala come INSTALLED, 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 del modulo e risorse. Dopo aver aggiornato i metadati dell'app, devi caricare i dati del modulo contenuti 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 già installato sul dispositivo scaricati 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 risorse o asset di un modulo facoltativo. Ciò è dovuto a un'incompatibilità tra WebView e SplitCompat su un livello API Android 28 e versioni precedenti.
  • Non puoi memorizzare nella cache gli oggetti Android ApplicationInfo, i relativi contenuti o che li contengono nella tua app. Devi sempre recuperare questi oggetti in base alle esigenze del 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 di funzionalità sono attualmente installati sul dispositivo: puoi chiamare SplitInstallManager.getInstalledModules(), che restituisce 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. Vale a dire che il dispositivo le disinstalla in background secondo necessità per risparmiare spazio di archiviazione. Puoi verificare che il dispositivo abbia ha eliminato un modulo richiamando SplitInstallManager.getInstalledModules() e ispezionare il risultato, come descritto nella sezione precedente.

Scarica risorse linguistiche aggiuntive

Con gli app bundle, i dispositivi scaricano solo il codice e le risorse richiedono l'esecuzione dell'app. Quindi, per le risorse linguistiche, il dispositivo di un utente scarica solo le risorse linguistiche dell'app che corrispondono a una o più lingue attualmente selezionato nelle impostazioni del dispositivo.

Se vuoi che la tua app abbia accesso a risorse linguistiche aggiuntive, ad esempio Ad esempio, per implementare un selettore lingua in-app, puoi usare la funzionalità Raccolta per scaricarla on demand. Il processo è simile a quello della scaricare 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à. Vale a dire che puoi monitorare lo stato della richiesta come faresti normalmente.

Se la tua app non richiede immediatamente le risorse linguistiche aggiuntive, può rimandare l'installazione per 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 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 usare risorse linguistiche che la tua 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);
}

Per applicare queste modifiche, devi ricreare la tua attività dopo aver installato la nuova lingua e pronta per l'uso. Puoi utilizzare lo 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 le risorse aggiuntive all'indirizzo in qualsiasi momento. Prima di richiedere una disinstallazione, è consigliabile stabilire quale lingue sono attualmente installate, come segue.

Kotlin

val installedLanguages: Set<String> = splitInstallManager.installedLanguages

Java

Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();

Puoi quindi decidere quali lingue disinstallare utilizzando il 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 svolgere senza collegarti al Play Store:

In questa pagina viene descritto come eseguire il deployment degli APK divisi dell'app sul dispositivo di test in modo che che Play Feature Delivery utilizza automaticamente questi APK per simulare richieste, download, e installando moduli dal Play Store.

Anche se non devi apportare modifiche alla logica dell'app, devi devono soddisfare i seguenti requisiti:

di Gemini Advanced.

Crea un insieme di APK

Se non l'hai ancora fatto, crea gli APK divisi per la tua app, come segue:

  1. Crea un app bundle per la tua app utilizzando uno dei seguenti metodi:
  2. Utilizza bundletool per generare un insieme di APK per tutti i dispositivi con il seguente comando:

    bundletool build-apks --local-testing
      --bundle my_app.aab
      --output my_app.apks
    

Il flag --local-testing include metadati nel tuo APK e manifest comunica alla libreria Play Feature Delivery di utilizzare gli APK divisi locali per testare installando moduli delle funzionalità senza collegarsi al Play Store.

Esegui il deployment dell'app sul dispositivo

Dopo aver creato un insieme di APK utilizzando il flag --local-testing, usa bundletool per installare la versione di base della tua app e trasferire altre APK allo spazio di archiviazione locale del dispositivo. Puoi eseguire entrambe le azioni con 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 Play Feature Delivery utilizza gli APK che bundletool trasferiti 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 utilizzi bundletool con il flag --local-testing creare un insieme di APK e implementarli sul dispositivo di test, include metadati che indicano alla libreria Play Feature Delivery di passare automaticamente le chiamate API della tua app per richiamare FakeSplitInstallManager, anziché SplitInstallManager,

FakeSplitInstallManager include un flag booleano che puoi attivare per simula un errore di rete la prossima volta che la tua app richiede di installare un modulo. A 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);