Funktionsmodule ermöglichen es Ihnen, bestimmte Funktionen und Ressourcen voneinander zu trennen. aus dem Basismodul deiner App und füge sie deinem App Bundle hinzu. Bis Play Feature Delivery können Nutzer diese zum Beispiel später herunterladen und installieren, nachdem sie das Basis-APK Ihrer App bereits installiert haben.
Stellen Sie sich z. B. eine SMS-App vor, die Funktionen Bildnachrichten erfassen und senden, aber nur ein kleiner Prozentsatz der Nutzenden Bildnachrichten senden Es kann sinnvoll sein, Bildbotschaften als Funktionsmodul herunterladen. So wird der erste App-Download ist für alle Nutzer kleiner und nur die Nutzer, die Bildnachrichten senden, müssen um diese zusätzliche Komponente herunterzuladen.
Denken Sie daran, dass diese Art der Modularisierung den Code Ihrer App zu refaktorieren. Überlegen Sie also gut, die Funktionen der App am meisten davon profitieren würden, wenn sie für Nutzer on demand verfügbar sind. Um die optimalen Anwendungsfälle und Richtlinien für On-Demand-Funktionen besser zu verstehen, UX-Best Practices für die On-Demand-Auslieferung
Wenn Sie App-Funktionen nach und nach modularisieren möchten, erweiterte Lieferoptionen wie On-Demand-Lieferung die Bereitstellung bei der Installation konfigurieren.
Auf dieser Seite erfahren Sie, wie Sie Ihrem App-Projekt ein Funktionsmodul hinzufügen und für die On-Demand-Auslieferung konfigurieren. Bevor Sie beginnen, müssen Sie Android Studio 3.5 oder höher und das Android Gradle-Plug-in 3.5.0 oder höher verwenden.
Neues Modul für On-Demand-Lieferung konfigurieren
Am einfachsten erstellen Sie ein neues Funktionsmodul mit Android Studio 3.5 oder höher Da Funktionsmodule inhärent vom Basis-App-Modul abhängig sind, können Sie sie nur zu bereits vorhandenen App-Projekten hinzufügen.
So fügen Sie Ihrem App-Projekt mit Android Studio ein Funktionsmodul hinzu:
- Öffnen Sie Ihr App-Projekt in der IDE, falls Sie dies noch nicht getan haben.
- Wählen Sie in der Menüleiste Datei > Neu > Neues Modul aus.
- Wählen Sie im Dialogfeld Neues Modul erstellen Modul für dynamische Funktionen und klicken Sie auf Weiter.
- Führen Sie im Abschnitt Configure your new module (Ihr neues Modul konfigurieren) die folgenden Schritte aus:
Folgendes:
- Wählen Sie das Basisanwendungsmodul für Ihr App-Projekt aus aus dem Drop-down-Menü aus.
- Geben Sie einen Modulnamen an. Anhand dieses Namens identifiziert die IDE das Modul als Gradle-Unterprojekt in der Gradle-Konfigurationsdatei. Wenn Sie Ihr App-Bundle erstellen, verwendet Gradle das letzte Element des Namens des Unterprojekts, um das
<manifest split>
-Attribut in das Manifest des Funktionsmoduls einzufügen. - Geben Sie den Paketnamen des Moduls an. Standardmäßig schlägt Android Studio einen Paketnamen vor, der den Namen des Stammpakets des Basismoduls mit dem Modulnamen kombiniert, den Sie im vorherigen Schritt angegeben haben.
- Wählen Sie die Mindest-API-Ebene aus, die das Modul unterstützen soll. Dieser Wert sollte mit dem des Basismoduls übereinstimmen.
- Klicken Sie auf Weiter.
Führen Sie im Bereich Downloadoptionen für Module folgende Schritte aus:
Geben Sie den Modultitel mit bis zu 50 Zeichen an. Die Plattform verwendet diesen Titel, um das Modul für Nutzer zu identifizieren, z. B. in folgenden Fällen: um zu bestätigen, dass der Nutzer das Modul herunterladen möchte. Aus diesem Grund muss das Basismodul Ihrer App den Modultitel als Stringressource enthalten, die Sie übersetzen können. Wenn Sie das Modul mit Android Studio erstellen, fügt die IDE dem Basismodul die Stringressource hinzu und fügt den folgenden Eintrag in das Manifest des Funktionsmoduls ein:
<dist:module ... dist:title="@string/feature_title"> </dist:module>
Wählen Sie im Drop-down-Menü unter Einschluss bei der Installation die Option Modul bei der Installation nicht einschließen aus. Android Studio fügt das Folgende in das Manifest des Moduls ein, um Ihre Auswahl widerzuspiegeln:
<dist:module ... > <dist:delivery> <dist:on-demand/> </dist:delivery> </dist:module>
Klicken Sie das Kästchen neben Zusammenführen an, wenn dieses Modul auf Geräten mit Android 4.4 (API-Level 20) und niedriger verfügbar sein und in Multi-APKs enthalten sein soll. Sie können also das On-Demand-Verhalten für dieses Modul aktivieren und die Zusammenführung deaktivieren, um es auf Geräten zu entfernen, die das Herunterladen und Installieren von unterteilten APKs nicht unterstützen. Android Studio fügt das Folgende in das Manifest des Moduls ein, um Ihre Auswahl widerzuspiegeln:
<dist:module ...> <dist:fusing dist:include="true | false" /> </dist:module>
Klicken Sie auf Fertig.
Nachdem Android Studio das Modul erstellt hat, können Sie den Inhalt im Bereich Project (Projekt) prüfen. Wählen Sie dazu in der Menüleiste View > Tool Windows > Project (Ansicht > Toolfenster > Projekt) aus. Der Standardcode, die Ressourcen und die Organisation sollten denen des Standard-App-Moduls ähneln.
Als Nächstes müssen Sie die On-Demand-Installationsfunktion mit der Play Feature Delivery-Bibliothek implementieren.
Play Feature Delivery-Bibliothek in Ihr Projekt aufnehmen
Bevor Sie beginnen können, müssen Sie Fügen Sie Ihrem Projekt die Play Feature Delivery Library hinzu.
On-Demand-Modul anfordern
Wenn deine App ein Funktionsmodul verwenden muss, kann sie währenddessen ein Modul anfordern.
dass es sich im Vordergrund befindet,
SplitInstallManager
. Bei einer Anfrage muss Ihre App den Namen des Moduls angeben, wie er durch das split
-Element im Manifest des Zielmoduls definiert ist. Wenn Sie
Funktionsmodul erstellen
über Android Studio verwendet das Build-System den von Ihnen angegebenen Modulnamen
um diese Eigenschaft bei der Kompilierung in das Manifest des Moduls einzufügen.
Weitere Informationen finden Sie in den
Manifeste für Funktionsmodule.
Angenommen, eine App hat ein On-Demand-Modul zum Erfassen und Senden
Nachrichten mit der Kamera des Geräts und dieses On-Demand-Modul
gibt split="pictureMessages"
in seinem Manifest an. Im folgenden Beispiel wird über SplitInstallManager
das pictureMessages
-Modul (zusammen mit einem zusätzlichen Modul für einige Angebotsfilter) angefordert:
// 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 -> ... }
// 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 -> { ... });
Wenn Ihre App ein On-Demand-Modul anfordert, verwendet die Play Feature Delivery Library eine „Fire-and-forget“-Strategie. Das heißt, es sendet die Anforderung zum Herunterladen der mit der Plattform, aber es wird nicht überwacht, erfolgreich war. Wenn Sie den Nutzerfluss nach der Installation fortsetzen oder Fehler ordnungsgemäß behandeln möchten, müssen Sie den Anfragestatus beobachten.
Hinweis:Sie können auch eine Funktionsmodul, das bereits auf dem Gerät installiert ist. Die API die Anfrage sofort als abgeschlossen gilt, wenn erkannt wird, dass das Modul bereits installiert haben. Außerdem aktualisiert Google Play das Modul, nachdem es installiert wurde. automatisch. Wenn Sie also eine neue Version Ihres App-Bundles hochladen, aktualisiert die Plattform alle installierten APKs, die zu Ihrer App gehören. Weitere Informationen finden Sie unter App-Updates verwalten.
Um Zugriff auf den Code und die Ressourcen des Moduls zu haben, muss Ihre App Aktivieren Sie SplitCompat. Für Android Instant Apps ist SplitCompat nicht erforderlich.
Installation von On-Demand-Modulen verschieben
Wenn ein On-Demand-Modul nicht sofort mit deiner App heruntergeladen und installiert werden soll, kannst du die Installation auf einen Zeitpunkt verschieben, an dem die App im Hintergrund ausgeführt wird. Für Wenn Sie beispielsweise Werbematerial für eine spätere Veröffentlichung für Ihre App.
Sie können ein Modul mit der Methode deferredInstall()
angeben, um es später herunterzuladen, wie unten gezeigt. Im Gegensatz zu
SplitInstallManager.startInstall()
,
Ihre App muss nicht im Vordergrund ausgeführt werden, um eine Anfrage
verzögerte Installation.
// 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"))
// 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"));
Anfragen für verzögerte Installationen
sind Best-Effort-Anfragen,
Fortschritt. Bevor Sie also versuchen, auf ein Modul zuzugreifen, das Sie für die verzögerte Installation angegeben haben, sollten Sie prüfen, ob das Modul installiert wurde. Wenn das Modul sofort verfügbar sein muss, verwenden Sie stattdessen SplitInstallManager.startInstall()
, um es anzufordern, wie im vorherigen Abschnitt gezeigt.
Anfragestatus überwachen
Wenn Sie eine Fortschrittsanzeige aktualisieren, nach der Installation einen Intent auslösen oder einen Fehler bei einer Anfrage ordnungsgemäß verarbeiten möchten, müssen Sie auf Statusaktualisierungen von der asynchronen SplitInstallManager.startInstall()
-Aufgabe warten.
Bevor Sie Updates für Ihre Installationsanfrage erhalten können, müssen Sie einen Listener registrieren und die Sitzungs-ID für die Anfrage abrufen, wie unten dargestellt.
// 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)
// 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);
Anfragefehler verarbeiten
Beachten Sie, dass die On-Demand-Installation von Funktionsmodulen So wie die Installation von Apps nicht immer erfolgreich ist. Fehler bei der Installation können folgende Ursachen haben: Probleme wie zu wenig Speicherplatz, keine Netzwerkverbindung oder im Google Play Store angemeldet sind. In unseren UX-Richtlinien für die On-Demand-Auslieferung finden Sie Vorschläge, wie Sie diese Situationen aus der Perspektive der Nutzer reibungslos bewältigen können.
Codeweise sollten Sie Fehler beim Herunterladen oder Installieren eines Moduls beheben.
mit addOnFailureListener()
, wie unten gezeigt:
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. } } } } }
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. } } } }); }
In der folgenden Tabelle werden die Fehlerstatus beschrieben, die Ihre App möglicherweise verarbeiten muss:
Fehlercode | Beschreibung | Vorgeschlagene Maßnahme |
---|---|---|
ACTIVE_SESSIONS_LIMIT_EXCEEDED (Aktiv) | Die Anfrage wurde abgelehnt, weil mindestens ein Element vorhanden ist die gerade heruntergeladen wird. | Prüfen Sie, ob noch Anfragen heruntergeladen werden, wie im Beispiel oben dargestellt. |
MODULE_UNAVAILABLE | Google Play kann das angeforderte Modul nicht finden. auf der aktuell installierten Version der App, des Geräts und des Google Play-Kontos des Nutzers Konto. | Wenn der Nutzer keinen Zugriff auf das Modul hat, benachrichtigen Sie ihn. |
INVALID_REQUEST | Google Play hat die Anfrage erhalten, aber die Anfrage ist ungültig. | Prüfen Sie, ob die in der Anfrage enthaltenen Informationen vollständig und korrekt sind. |
SITZUNG_NICHT_GEFUNDEN | Für eine bestimmte Sitzungs-ID wurde keine Sitzung gefunden. | Wenn Sie den Status einer Anfrage anhand der Sitzungs-ID überwachen möchten, achten Sie darauf, dass die Sitzungs-ID korrekt ist. |
API_NICHT_VERFÜGBAR | Die Play Feature Delivery Library wird auf dem aktuellen Gerät nicht unterstützt. Das Gerät kann also keine Funktionen auf Abruf herunterladen und installieren. | Für Geräte mit Android 4.4 (API-Level 20) oder niedriger:
Funktionsmodule erst bei der Installation über die
Manifest-Property „dist:fusing “. Weitere Informationen finden Sie in den
Funktionsmodul-Manifest.
|
NETWORK_ERROR | Die Anfrage ist aufgrund eines Netzwerkfehlers fehlgeschlagen. | Bitten Sie den Nutzer, entweder eine Netzwerkverbindung herzustellen oder zu einem anderen Netzwerk zu wechseln. |
ZUGRIFF_DENIED | Die App kann die Anfrage aufgrund unzureichender Berechtigungen nicht registrieren. | Dies ist normalerweise der Fall, wenn die App im Hintergrund ausgeführt wird. Senden Sie die Anfrage, wenn die App in den Vordergrund zurückkehrt. |
INKOMPATIBLE_MIT_VORHANDENEM_SESSION | Die Anfrage enthält mindestens ein Modul, das bereits angefordert, aber noch nicht installiert. | Erstellen Sie entweder eine neue Anfrage, die keine bereits von Ihrer App angeforderten Module enthält, oder warten Sie, bis die Installation aller derzeit angeforderten Module abgeschlossen ist, bevor Sie die Anfrage noch einmal versuchen.
Beachten Sie, dass das Anfordern eines bereits installierten Moduls nicht zu einem Fehler führt. |
SERVICE_DIED | Der für die Verarbeitung der Anfrage zuständige Dienst ist inaktiv. | Wiederholen Sie die Anfrage.
Dein |
INSUFFICIENT_STORAGE | Auf dem Gerät ist nicht genügend freier Speicherplatz vorhanden, um die Funktion zu installieren. -Modul. | Informieren Sie den Nutzer, dass er nicht genügend Speicherplatz hat, um diese Funktion zu installieren. |
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR | SplitCompat konnte das Funktionsmodul nicht laden. | Diese Fehler sollten sich nach dem nächsten App-Neustart automatisch beheben. |
PLAY_STORE_NOT_FOUND | Die Play Store App ist nicht auf dem Gerät installiert. | Teile dem Nutzer mit, dass zum Herunterladen dieser App die Play Store App erforderlich ist. . |
APP_NICHT_EIGENTUM | Die App wurde nicht von Google Play installiert und die Funktion kann nicht heruntergeladen werden. Dieser Fehler kann nur bei verzögerten Installationen auftreten. | Wenn du möchtest, dass der Nutzer die App bei Google Play erwirbt, verwende
startInstall() , die die erforderlichen
Nutzerbestätigung. |
INTERNAL_ERROR | Im Play Store ist ein interner Fehler aufgetreten. | Wiederholen Sie die Anfrage. |
Wenn ein Nutzer das Herunterladen eines On-Demand-Moduls anfordert und ein Fehler auftritt, sollten Sie sich ein Dialogfeld mit zwei Optionen für den Nutzer anzeigen lassen: Versuchen Sie es erneut, wodurch die Anfrage erneut gesendet wird, und Cancel, wodurch die -Anforderung). Für zusätzlichen Support sollten Sie auch einen Hilfe-Link angeben, über den Nutzer zur Google Play-Hilfe weitergeleitet werden.
Statusaktualisierungen verarbeiten
Nachdem Sie einen Listener registriert und die Sitzungs-ID für Ihre Anfrage aufgezeichnet haben,
StateUpdatedListener.onStateUpdate()
verwenden
um Statusänderungen zu verarbeiten, wie unten gezeigt.
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. } } } }
@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. } } }
Die möglichen Status für Ihre Installationsanfrage sind in der folgenden Tabelle beschrieben.
Anfragestatus | Beschreibung | Vorgeschlagene Maßnahme |
---|---|---|
AUSSTEHEND | Der Antrag wurde akzeptiert und der Download sollte bald beginnen. | Initialisieren Sie UI-Komponenten wie eine Fortschrittsanzeige, um den Nutzern Feedback zum Download zu geben. |
REQUIRES_USER_CONFIRMATION | Der Download erfordert eine Nutzerbestätigung. In den meisten Fällen tritt dieser Status auf, wenn die App nicht über Google Play installiert wurde. | Bitten Sie den Nutzer, den Download der Funktion über Google Play zu bestätigen. Weitere Informationen finden Sie im Abschnitt zur eine Nutzerbestätigung einholen. |
Downloads | Download läuft. | Wenn du einen Fortschrittsbalken für den Download bereitstellst, verwende die Methoden SplitInstallSessionState.bytesDownloaded() und SplitInstallSessionState.totalBytesToDownload() , um die Benutzeroberfläche zu aktualisieren (siehe Codebeispiel über dieser Tabelle). |
HERUNTERGELADEN | Das Gerät hat das Modul heruntergeladen, aber die Installation hat noch nicht begonnen. | Apps sollten SplitCompat aktivieren um Zugriff auf heruntergeladene Module zu erhalten und diesen Status zu vermeiden. Dies ist erforderlich, um auf den Code und die Ressourcen des Funktionsmoduls zuzugreifen. |
Installation... | Auf dem Gerät wird derzeit das Modul installiert. | Aktualisieren Sie die Fortschrittsanzeige. Dieser Zustand ist in der Regel kurz. |
INSTALLIERT | Das Modul ist auf dem Gerät installiert. | Zugriffscode und Ressource im Modul, um mit der User Journey fortzufahren.
Wenn das Modul für eine Android Instant App mit Android 8.0 (API-Level 26) bestimmt ist
oder höher müssen Sie |
FEHLER | Die Anfrage ist fehlgeschlagen, bevor das Modul auf dem Gerät installiert wurde. | Bitten Sie den Nutzer, den Vorgang noch einmal zu versuchen oder abzubrechen. |
WIRD ABGEBROCHEN | Auf dem Gerät wird die Anfrage gerade abgebrochen. | Weitere Informationen finden Sie im Abschnitt zur Installationsanfrage abbrechen. |
GESTRICHEN | Die Anfrage wurde abgebrochen. |
Nutzerbestätigung einholen
In einigen Fällen ist bei Google Play eine Nutzerbestätigung erforderlich, bevor ein Downloadanfrage ausgeführt wird. Das ist beispielsweise der Fall, wenn Ihre App nicht von Google Play installiert wurde oder Sie einen großen Download über mobile Daten versuchen. In solchen Fällen
der Status der Anfrage meldet REQUIRES_USER_CONFIRMATION
und Ihre App
muss die Bestätigung des Nutzers eingeholt werden, bevor das Gerät die Datei herunterladen und
die Module in der Anfrage zu installieren. Um eine Bestätigung zu erhalten, muss Ihre App
fordern Sie den Nutzer so auf:
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) } ... }
@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); } ... }
Sie können einen Launcher für Aktivitätsergebnisse mit dem integrierten Vertrag ActivityResultContracts.StartIntentSenderForResult
registrieren. Weitere Informationen finden Sie unter Aktivitätsergebnis-APIs.
Der Status der Anfrage wird je nach Nutzerantwort aktualisiert:
- Wenn der Nutzer die Bestätigung akzeptiert, ändert sich der Antragsstatus zu
PENDING
und der Download wird fortgesetzt. - Lehnt der Nutzer die Bestätigung ab, ändert sich der Anfragestatus in
CANCELED
- Wenn der Nutzer keine Auswahl trifft, bevor das Dialogfeld geschlossen wird, bleibt der Anfragestatus
REQUIRES_USER_CONFIRMATION
. Ihre App kann den Nutzer noch einmal auffordern, die Anfrage abzuschließen.
Wenn Sie einen Callback mit der Antwort des Nutzers erhalten möchten, können Sie den ActivityResultCallback wie unten gezeigt überschreiben.
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. } }
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. } });
Installationsanfrage stornieren
Wenn Ihre Anwendung eine Anfrage vor der Installation abbrechen muss, kann sie
cancelInstall()
-Methode mithilfe der Sitzungs-ID der Anfrage (siehe unten).
splitInstallManager // Cancels the request for the given session ID. .cancelInstall(mySessionId)
splitInstallManager // Cancels the request for the given session ID. .cancelInstall(mySessionId);
Auf Module zugreifen
So greifen Sie nach dem Download aus einem heruntergeladenen Modul auf Code und Ressourcen zu: muss Ihre App die SplitCompat-Bibliothek für deine App und jede Aktivität in den Funktionsmodulen deiner App Downloads.
Sie sollten jedoch beachten, dass die Plattform folgende Vorteile bietet: Einschränkungen beim Zugriff auf Inhalte eines Moduls für eine Zeit (Tage, manchmal Fälle), nachdem Sie das Modul heruntergeladen haben:
- Die Plattform kann keine neuen Manifesteinträge anwenden, die durch das Modul eingeführt wurden.
- Die Plattform kann nicht auf die Ressourcen des Moduls für System-UI-Komponenten wie Benachrichtigungen zugreifen. Wenn Sie solche Ressourcen sofort benötigen, sollten Sie und in das Basismodul Ihrer App einfügen.
SplitCompat aktivieren
Damit Ihre App auf Code und Ressourcen aus einem heruntergeladenen Modul zugreifen kann, müssen Sie SplitCompat mit einer der in den folgenden Abschnitten beschriebenen Methoden aktivieren.
Nachdem Sie SplitCompat für Ihre App aktiviert haben, müssen Sie SplitCompat auch für jede Aktivität in den Funktionsmodulen aktivieren, auf die Ihre App zugreifen soll.
SplitCompatApplication im Manifest deklarieren
Die einfachste Möglichkeit, SplitCompat zu aktivieren, besteht darin, SplitCompatApplication
zu deklarieren
als abgeleitete Application
-Klasse in
in das Manifest Ihrer App einfügen:
<application
...
android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
</application>
Nachdem die App auf einem Gerät installiert wurde, kannst du über Funktionsmodule automatisch heruntergeladen werden.
SplitCompat zur Laufzeit aufrufen
Sie können SplitCompat auch bei bestimmten Aktivitäten oder Diensten zur Laufzeit aktivieren.
Diese Aktivierung von SplitCompat ist erforderlich, um Aktivitäten zu starten, die in
Funktionsmodule. Überschreiben Sie dazu attachBaseContext
wie unten gezeigt.
Wenn Sie eine benutzerdefinierte Application-Klasse haben,
stattdessen erweitern können,
SplitCompatApplication
um SplitCompat für Ihre App zu aktivieren:
class MyApplication : SplitCompatApplication() { ... }
public class MyApplication extends SplitCompatApplication { ... }
SplitCompatApplication
überschreibt einfach ContextWrapper.attachBaseContext()
um SplitCompat.install(Context applicationContext)
einzuschließen. Wenn Sie nicht möchten, dass Ihre Application
-Klasse SplitCompatApplication
erweitert, können Sie die attachBaseContext()
-Methode manuell überschreiben. Gehen Sie dazu so vor:
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) // Emulates installation of future on demand modules using SplitCompat. SplitCompat.install(this) }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // Emulates installation of future on demand modules using SplitCompat. SplitCompat.install(this); }
Wenn Ihr On-Demand-Modul sowohl mit Instant Apps als auch mit installierten Apps kompatibel ist, können Sie SplitCompat bedingt aufrufen. Gehen Sie dazu so vor:
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) if (!InstantApps.isInstantApp(this)) { SplitCompat.install(this) } }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); if (!InstantApps.isInstantApp(this)) { SplitCompat.install(this); } }
SplitCompat für Modulaktivitäten aktivieren
Nachdem Sie SplitCompat für Ihre Basis-App aktiviert haben, müssen Sie SplitCompat aktivieren
für jede Aktivität, die deine App in einem Funktionsmodul herunterlädt. Gehen Sie dazu wie folgt vor:
Verwenden Sie die Methode SplitCompat.installActivity()
so:
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) // Emulates installation of on demand modules using SplitCompat. SplitCompat.installActivity(this) }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // Emulates installation of on demand modules using SplitCompat. SplitCompat.installActivity(this); }
Auf in Funktionsmodulen definierte Komponenten zugreifen
Eine in einem Funktionsmodul definierte Aktivität starten
Nachdem Sie SplitCompat aktiviert haben, können Sie Aktivitäten, die in Funktionsmodulen definiert sind, mit startActivity()
starten.
startActivity(Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...))
startActivity(new Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...));
Der erste Parameter für setClassName
ist der Paketname der App und der Parameter
Der zweite Parameter ist der vollständige Klassenname der Aktivität.
Wenn Sie eine Aktivität in einem Funktionsmodul haben, das Sie on demand heruntergeladen haben, Aktivieren Sie SplitCompat in der Aktivität.
In einem Funktionsmodul definierten Dienst starten
Sie können Dienste, die in Funktionsmodulen definiert sind, mit
startService()
nachdem Sie SplitCompat aktiviert haben.
startService(Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...))
startService(new Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...));
In einem Feature-Modul definierte Komponente exportieren
Exportierte Android-Komponenten sollten nicht in optionale Module aufgenommen werden.
Das Build-System führt Manifesteinträge für alle Module in das Basismodul zusammen. Wenn ein optionales Modul eine exportierte Komponente enthält, ist diese bereits vor der Installation des Moduls zugänglich und kann bei Aufruf aus einer anderen App aufgrund fehlenden Codes zu einem Absturz führen.
Das ist bei internen Komponenten kein Problem, da nur die App darauf zugreift. So kann die App prüfen, ob das Modul installiert ist, bevor sie auf die Komponente zugreift.
Wenn Sie eine exportierte Komponente benötigen und deren Inhalt in einer optionalen Komponente
können Sie ein Proxy-Muster implementieren.
Sie können dies tun, indem Sie eine Proxy-Exportkomponente in der Basis hinzufügen.
Beim Zugriff kann die Proxy-Komponente prüfen, ob das Modul vorhanden ist,
enthält den Inhalt. Wenn das Modul vorhanden ist, kann die Proxykomponente die interne Komponente über eine Intent
aus dem Modul starten und den Intent aus der aufrufenden App weiterleiten. Ist das Modul nicht vorhanden, kann die Komponente das Modul herunterladen oder eine entsprechende Fehlermeldung an die aufrufende App zurückgeben.
Auf Code und Ressourcen aus installierten Modulen zugreifen
Wenn Sie SplitCompat für Ihre Basis aktivieren Anwendungskontext und die Aktivitäten in Ihrem Funktionsmodul haben, können Sie die Funktion Code und Ressourcen aus einem Funktionsmodul abrufen, als ob es Teil des Basis-APKs wäre, sobald das optionale Modul installiert ist.
Zugriffscode aus einem anderen Modul
Über ein Modul auf Basiscode zugreifen
Code in Ihrem Basismodul kann direkt von anderen Modulen verwendet werden. Sie müssen nichts Besonderes tun. importieren und verwenden Sie einfach die benötigten Kurse.
Auf Modulcode aus einem anderen Modul zugreifen
Auf ein Objekt oder eine Klasse in einem Modul kann nicht direkt aus einem anderen Modul statisch zugegriffen werden. Es ist aber möglich, indirekt über Reflection darauf zuzugreifen.
Aufgrund der Leistungskosten von Reflexionen sollten Sie darauf achten, wie oft dies geschieht. Verwenden Sie für komplexe Anwendungsfälle Frameworks wie Abhängigkeitsinjektionen wie Dagger 2, um einen einzelnen Reflexionsaufruf pro App-Lebensdauer.
Um die Interaktionen mit dem Objekt nach der Instanziierung zu vereinfachen, wird empfohlen, im Basismodul eine Schnittstelle und deren Implementierung in des Funktionsmoduls. Beispiel:
// 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();
// 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();
Auf Ressourcen und Assets aus einem anderen Modul zugreifen
Nachdem ein Modul installiert wurde, können Sie auf die Ressourcen und Assets innerhalb des Moduls auf standardmäßige Weise zugreifen. Es gibt jedoch zwei Einschränkungen:
- Wenn Sie über ein anderes Modul auf eine Ressource zugreifen, Zugriff auf die Ressourcen-ID haben. Die Ressource kann jedoch trotzdem auf die über den Namen zugegriffen wird. Das Paket, auf das verwiesen werden soll, ist das Paket des Moduls, in dem die Ressource definiert ist.
- Wenn Sie auf Assets oder Ressourcen zugreifen möchten, die in einer neu installierten Modul eines anderen installierten Moduls Ihrer App müssen Sie dies über das Anwendungskontext. Der Kontext der Komponente, die auf die Ressourcen zuzugreifen versucht, wird noch nicht aktualisiert. Alternativ können Sie diese Komponente neu erstellen (z. B. durch Aufrufen Activity.recreate()) oder SplitCompat nach dem Funktionsmodul neu darauf installieren Installation.
Nativen Code mit der On-Demand-Auslieferung in einer App laden
Wir empfehlen die Verwendung von ReLinker, um alle native Bibliotheken, wenn Sie die On-Demand-Bereitstellung von Funktionsmodulen nutzen. Mit ReLinker wird ein Problem beim Laden nativer Bibliotheken nach der Installation eines Funktionsmoduls behoben. Weitere Informationen zum ReLinker findest du in der Tipps zu Android JNI
Nativen Code aus einem optionalen Modul laden
Sobald ein Split installiert ist, empfehlen wir, den nativen Code über ReLinker: Für Instant-Apps sollten Sie diese spezielle Methode verwenden.
Wenn Sie System.loadLibrary()
verwenden, um Ihren nativen Code und Ihren nativen
Abhängigkeit von einer anderen Bibliothek im Modul aufweist, müssen Sie
diese andere Bibliothek zuerst laden.
Wenn Sie ReLinker verwenden, ist der entsprechende Vorgang Relinker.recursively().loadLibrary()
.
Wenn Sie dlopen()
in nativem Code verwenden, um eine in einem optionalen Modul definierte Bibliothek zu laden, funktioniert das nicht mit relativen Bibliothekspfaden.
Die beste Lösung besteht darin, den absoluten Pfad der Bibliothek aus dem Java-Code abzurufen.
über ClassLoader.findLibrary()
und dann in deinem dlopen()
-Aufruf verwenden.
Tun Sie dies, bevor Sie den nativen Code eingeben, oder verwenden Sie einen JNI-Aufruf aus Ihrem
nativen Code in Java importieren können.
Auf installierte Android Instant Apps zugreifen
Nachdem ein Modul der Android Instant App als INSTALLED
gemeldet wurde, können Sie auf seine
Code und Ressourcen mit einer aktualisierten App
Context (Kontext): A
Kontext, den deine App vor der Installation eines Moduls erstellt (z. B.
das bereits in einer Variablen gespeichert ist, enthält nicht den Inhalt der neuen
-Modul. Ein neuer Kontext funktioniert jedoch – dieser kann beispielsweise mit createPackageContext
abgerufen werden.
// 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 } } } }
// 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(); } } }
Android Instant Apps unter Android 8.0 und höher
Wenn ein On-Demand-Modul für eine Android Instant App unter Android 8.0 angefordert wird
(API-Level 26) und höher, haben Sie nach einer Installationsanfrage als INSTALLED
gemeldet, dass Sie
die App mit dem Kontext des neuen Moduls über einen Aufruf von
SplitInstallHelper.updateAppInfo(Context context)
Andernfalls kennt die App den Code und die Ressourcen des Moduls noch nicht. Nachdem Sie die Metadaten der App aktualisiert haben, sollten Sie die
des nächsten Hauptthread-Ereignisses durch Aufrufen eines neuen
Handler
, wie unten gezeigt:
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 ... } } } } } }
@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(); ... } }); } } } }
C/C++-Bibliotheken laden
Wenn Sie C/C++-Bibliotheken aus einem Modul laden möchten, das bereits auf dem Gerät installiert ist
Instant App heruntergeladen haben, verwenden Sie
SplitInstallHelper.loadLibrary(Context context, String libName)
,
wie unten dargestellt:
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”) ... } } } }
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”); ... } } }
Bekannte Einschränkungen
- Android WebView kann nicht in einer Aktivität verwendet werden, die auf Ressourcen oder Assets aus einem optionalen Modul zugreift. Dies ist auf Inkompatibilität zurückzuführen. zwischen WebView und SplitCompat auf Android-API-Level 28 und niedriger.
- Sie können keine Android
ApplicationInfo
-Objekte, deren Inhalte oder -Objekte, die sie in Ihrer App enthalten. Sie sollten diese Objekte immer abrufen. bei Bedarf aus einem App-Kontext. Wenn Sie solche Objekte im Cache speichern, kann die App beim Installieren eines Funktionsmoduls abstürzen.
Installierte Module verwalten
Wenn Sie prüfen möchten, welche Funktionsmodule derzeit auf dem Gerät installiert sind, können Sie SplitInstallManager.getInstalledModules()
aufrufen. Daraufhin wird eine Set<String>
mit den Namen der installierten Module zurückgegeben, wie unten dargestellt.
val installedModules: Set<String> = splitInstallManager.installedModules
Set<String> installedModules = splitInstallManager.getInstalledModules();
Module deinstallieren
Sie können das Gerät auffordern, Module zu deinstallieren, indem Sie SplitInstallManager.deferredUninstall(List<String> moduleNames)
aufrufen, wie unten gezeigt.
// Specifies two feature modules for deferred uninstall. splitInstallManager.deferredUninstall(listOf("pictureMessages", "promotionalFilters"))
// Specifies two feature modules for deferred uninstall. splitInstallManager.deferredUninstall(Arrays.asList("pictureMessages", "promotionalFilters"));
Die Deinstallation des Moduls erfolgt nicht sofort. Das Gerät deinstalliert sie bei Bedarf im Hintergrund, um Speicherplatz zu sparen.
Sie können prüfen, ob das Gerät
hat ein Modul durch Aufrufen
SplitInstallManager.getInstalledModules()
und überprüfen das Ergebnis, wie im vorherigen Abschnitt beschrieben.
Zusätzliche Sprachressourcen herunterladen
Bei App-Bundles werden auf den Geräten nur der Code und die Ressourcen heruntergeladen, die zum Ausführen Ihrer App erforderlich sind. Bei Sprachressourcen werden also nur die Sprachressourcen Ihrer App auf das Gerät des Nutzers heruntergeladen, die der oder den in den Geräteeinstellungen aktuell ausgewählten Sprachen entsprechen.
Wenn Sie möchten, dass Ihre App auf zusätzliche Sprachressourcen zugreifen kann, Um beispielsweise eine In-App-Sprachauswahl zu implementieren, kannst du die Play Feature Delivery Mediathek, um sie bei Bedarf herunterzuladen. Der Vorgang ähnelt dem Herunterladen eines Funktionsmoduls, wie unten dargestellt.
// 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)
// 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);
Die Anfrage wird wie eine Anfrage für ein Funktionsmodul behandelt. Das heißt: können Sie wie gewohnt den Anfragestatus überwachen.
Wenn die zusätzlichen Sprachressourcen für Ihre App nicht sofort erforderlich sind, können Sie die Installation wie unten gezeigt auf einen Zeitpunkt verschieben, an dem die App im Hintergrund ausgeführt wird.
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
Auf heruntergeladene Sprachressourcen zugreifen
Damit Ihre App auf heruntergeladene Sprachressourcen zugreifen kann, muss sie die Methode SplitCompat.installActivity()
in der Methode attachBaseContext()
jeder Aktivität ausführen, für die Zugriff auf diese Ressourcen erforderlich ist, wie unten dargestellt.
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) SplitCompat.installActivity(this) }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); SplitCompat.installActivity(this); }
Für jede Aktivität, die Sie von Ihrer App heruntergeladen haben,
Basiskontext aktualisieren und eine neue Sprache über die
Configuration
:
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) }
@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); }
Damit diese Änderungen wirksam werden, müssen Sie Ihre Aktivitäten neu erstellen, nachdem die neue Sprache installiert und einsatzbereit ist. Sie können die
Activity#recreate()
-Methode.
when (state.status()) { SplitInstallSessionStatus.INSTALLED -> { // Recreates the activity to load resources for the new language // preference. activity.recreate() } ... }
switch (state.status()) { case SplitInstallSessionStatus.INSTALLED: // Recreates the activity to load resources for the new language // preference. activity.recreate(); ... }
Zusätzliche Sprachressourcen deinstallieren
Ähnlich wie bei Funktionsmodulen können Sie zusätzliche Ressourcen unter folgendem Link deinstallieren: jederzeit ändern. Bevor Sie eine Deinstallation beantragen, sollten Sie zuerst ermitteln, welche Sprachen derzeit installiert sind. Gehen Sie dazu so vor:
val installedLanguages: Set<String> = splitInstallManager.installedLanguages
Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();
Du kannst dann mithilfe der
deferredLanguageUninstall()
-Methode, wie unten gezeigt.
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
Modulinstallationen lokal testen
Mit der Play Feature Delivery Library können Sie die folgenden Funktionen Ihrer App lokal testen, ohne eine Verbindung zum Play Store herzustellen:
- Modulinstallationen anfordern und überwachen
- Beheben Sie Installationsfehler.
SplitCompat
verwenden um auf Module zuzugreifen.
Auf dieser Seite wird beschrieben, wie Sie die gesplitteten APKs Ihrer App auf Ihrem Testgerät bereitstellen, damit die Play Feature Delivery diese APKs automatisch verwendet, um das Anfordern, Herunterladen und Installieren von Modulen aus dem Play Store zu simulieren.
Sie müssen zwar keine Änderungen an der Logik Ihrer App vornehmen, die folgenden Anforderungen erfüllen:
- Laden Sie die aktuelle Version von
bundletool
herunter und installieren Sie sie. Sie benötigenbundletool
, um aus dem Bundle Ihrer App eine neue Reihe von installierbaren APKs zu erstellen.
APKs erstellen
Erstellen Sie die aufgeteilten APKs Ihrer App wie folgt, falls Sie dies noch nicht getan haben:
- Erstellen Sie mit einer der folgenden Methoden ein App-Bundle für Ihre App:
- Verwenden Sie Android Studio und das Android-Plug-in für Gradle zum Erstellen und Signieren ein Android App Bundle.
- App-Bundle über die Befehlszeile erstellen
Verwenden Sie
bundletool
, um eine Reihe von APKs für alle Geräte Konfigurationen mit dem folgenden Befehl:bundletool build-apks --local-testing --bundle
my_app.aab --outputmy_app.apks
Das Flag --local-testing
enthält Metadaten in den Manifesten Ihrer APKs, die die Play Feature Delivery Library darüber informieren, dass die lokal aufgeteilten APKs verwendet werden sollen, um die Installation von Funktionsmodulen zu testen, ohne eine Verbindung zum Play Store herzustellen.
App auf dem Gerät bereitstellen
Nachdem Sie mit dem Flag --local-testing
einen Satz von APKs erstellt haben:
bundletool
verwenden, um die Basisversion deiner App zu installieren und weitere zu übertragen
APKs in den lokalen Speicher Ihres Geräts hochladen. Beide Aktionen können Sie mit der
folgenden Befehl:
bundletool install-apks --apksmy_app.apks
Wenn Sie jetzt Ihre App starten und den Nutzerfluss zum Herunterladen und Installieren eines Funktionsmoduls abschließen, verwendet die Play Feature Delivery Library die APKs, die bundletool
auf den lokalen Speicher des Geräts übertragen wurden.
Netzwerkfehler simulieren
Um Modulinstallationen aus dem Play Store zu simulieren, verwendet die Play Feature Delivery Library eine Alternative zur SplitInstallManager
, die FakeSplitInstallManager
, um das Modul anzufordern. Wenn Sie bundletool
mit dem Flag --local-testing
verwenden
um eine Reihe von APKs zu erstellen und auf deinem Testgerät bereitzustellen,
enthält Metadaten, die die Play Feature Delivery Library anweisen, automatisch
Ihrer App zum Aufrufen von FakeSplitInstallManager
anstelle von
SplitInstallManager
FakeSplitInstallManager
enthält ein boolesches Flag, das Sie aktivieren können, um
einen Netzwerkfehler simulieren, wenn Ihre App das nächste Mal die Installation eines Moduls anfordert. Bis
in Ihren Tests auf FakeSplitInstallManager
zugreifen, können Sie eine Instanz davon abrufen.
mithilfe der
FakeSplitInstallManagerFactory
,
wie unten dargestellt:
// 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)
// 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);