On-Demand-Auslieferung konfigurieren

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 können Sie Ihrem App-Projekt ein Funktionsmodul hinzufügen On-Demand-Auslieferung konfigurieren. Bevor Sie beginnen, sollten Sie Sie benötigen Android Studio 3.5 oder höher und das Android-Gradle-Plug-in 3.5.0. oder höher.

Neues Modul für On-Demand-Auslieferung konfigurieren

Am einfachsten erstellen Sie ein neues Funktionsmodul mit Android Studio 3.5 oder höher Da Funktionsmodule ein Abhängigkeit vom Basis-App-Modul hat, können Sie sie nur zu vorhandenen App-Projekten.

So fügen Sie Ihrem App-Projekt mithilfe von Android Studio ein Funktionsmodul hinzu: gehen Sie wie folgt vor:

  1. Öffnen Sie Ihr App-Projekt in der IDE, falls Sie dies noch nicht getan haben.
  2. Wählen Sie Datei > Neu > Neues Modul aus.
  3. Wählen Sie im Dialogfeld Neues Modul erstellen Modul für dynamische Funktionen und klicken Sie auf Weiter.
  4. Führen Sie im Abschnitt Configure your new module (Ihr neues Modul konfigurieren) die folgenden Schritte aus: Folgendes: <ph type="x-smartling-placeholder">
      </ph>
    1. Wählen Sie das Basisanwendungsmodul für Ihr App-Projekt aus aus dem Drop-down-Menü aus.
    2. Geben Sie einen Modulnamen an. Die IDE verwendet diesen Namen, um die als Gradle-Unterprojekt in Ihrem Gradle-Einstellungsdatei Wenn Sie Ihr App Bundle erstellen, verwendet Gradle das letzte Element des Unterprojekts. Name zum Einfügen des Attributs <manifest split> in den Manifest des Funktionsmoduls.
    3. Geben Sie den Paketnamen des Moduls an. Standardmäßig zeigt Android Studio einen Paketnamen vorschlägt, der den Namen des Root-Pakets des Basismoduls und den Modulnamen, den Sie im vorherigen Schritt angegeben haben.
    4. Wählen Sie das Mindest-API-Level aus, das das Modul unterstützen soll. Dieser Wert sollte mit dem Wert des Basismoduls übereinstimmen.
  5. Klicken Sie auf Weiter.
  6. Führen Sie im Abschnitt Module Download Options (Optionen für den Moduldownload) folgende Schritte aus:

    1. 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. In diesem Fall muss das Basismodul deiner App den Modultitel als String-Ressource, den Sie übersetzen kann. Beim Erstellen des Moduls mit Android Studio fügt die Zeichenfolgenressource für Sie zum Basismodul hinzu und fügt die Zeichenfolge folgenden Eintrag im Manifest des Funktionsmoduls:

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. Wählen Sie im Drop-down-Menü unter Aufnahme bei der Installation die Option Do not das Modul bei der Installation einschließen. Android Studio schleust die folgen Sie im Manifest des Moduls entsprechend Ihrer Auswahl:

      <dist:module ... >
        <dist:delivery>
            <dist:on-demand/>
        </dist:delivery>
      </dist:module>
      
    3. Klicken Sie auf das Kästchen neben Fusing (Fühlen), wenn dieses Modul verfügbar sein soll. bis einschließlich Android 4.4 (API-Level 20) und in mit mehreren APKs. Sie können also das On-Demand-Verhalten für dieses Modul aktivieren. und das Zusammenführen deaktivieren, um sie bei Geräten, die den Unterteilte APKs herunterladen und installieren Android Studio schleust die folgen Sie im Manifest des Moduls entsprechend Ihrer Auswahl:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. Klicken Sie auf Fertig.

Nachdem Android Studio das Modul erstellt hat, überprüfen Sie seinen Inhalt im Bereich Project (Projekt) unter View > Tool Windows > Project (Ansicht > Tool-Fenster > Projekt) aus. Der Standardcode, die Standardressourcen und die Standardorganisation sollten ähnlich wie beim Standard-App-Modul.

Als Nächstes müssen Sie die On-Demand-Installation mithilfe der Play Feature Delivery-Bibliothek implementieren.

Google Play Feature Delivery Library in Ihr Projekt einbinden

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. im Vordergrund ausgeführt wird, SplitInstallManager . Wenn Sie eine muss Ihre App den Namen des Moduls gemäß der Definition split-Element im Manifest des Zielmoduls. 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 Bilder von Nachrichten über die Kamera des Geräts und dieses On-Demand-Modul gibt split="pictureMessages" in seinem Manifest an. Die Im folgenden Beispiel wird SplitInstallManager verwendet, um das pictureMessages-Objekt anzufordern. (zusammen mit einem zusätzlichen Modul für einige Werbefilter):

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 -> { ... });

Wenn deine App ein On-Demand-Modul anfordert, verwendet die Play Feature Delivery Library ein „Fire-and-Forget“-Strategie vor. Das heißt, es sendet die Anforderung zum Herunterladen der mit der Plattform, aber es wird nicht überwacht, erfolgreich war. Um die User Journey nach der bei der Installation oder bei Fehlern beseitigen müssen, überwachen Sie die Anfrage Bundesstaat.

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 alle installierten APKs, die zu deiner 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. Beachten Sie, dass SplitCompat nicht für Android Instant Apps erforderlich.

Installation von On-Demand-Modulen aufschieben

Wenn Ihre App nicht sofort ein On-Demand-Video herunterladen und installieren muss können Sie die Installation auf später verschieben, wenn 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 festlegen, dass ein Modul später heruntergeladen wird, indem Sie die deferredInstall() wie unten dargestellt. Im Gegensatz zu SplitInstallManager.startInstall(), Ihre App muss nicht im Vordergrund ausgeführt werden, um eine Anfrage verzögerte Installation.

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"));

Anfragen für verzögerte Installationen sind Best-Effort-Anfragen, Fortschritt. Bevor Sie auf ein Modul zugreifen, das Sie für der Installation sollten Sie Prüfen Sie, ob das Modul installiert wurde. Wenn Sie muss das Modul sofort verfügbar sein. Verwenden Sie SplitInstallManager.startInstall(), um sie anzufordern, wie im vorherigen Abschnitt gezeigt. .

Anfragestatus überwachen

Damit Sie eine Fortschrittsanzeige aktualisieren können, lösen Sie nach dem folgenden Ereignis einen Intent aus: oder bei Anfragefehlern auf Fehler geleitet werden, Statusaktualisierungen aus der asynchronen Aufgabe SplitInstallManager.startInstall(). Bevor Sie Updates für Ihre Installationsanfrage erhalten können, registrieren Sie ein Listener und rufen Sie die Sitzungs-ID für die Anfrage ab, wie unten gezeigt.

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);

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. Vorschläge zum Umgang mit solchen Situationen aus der Perspektive der Nutzenden anmutig ansehen, UX-Richtlinien für die On-Demand-Auslieferung

Codeweise sollten Sie Fehler beim Herunterladen oder Installieren eines Moduls beheben. mit addOnFailureListener(), wie unten gezeigt:

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.
                    }
                }
            }
        });
}

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 es Anfragen gibt, die noch heruntergeladen werden (siehe Abbildung). im obigen Beispiel.
MODULE_UNVERFÜGBAR 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.
UNGÜLTIGE_ANFRAGE 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. Status einer Anfrage überwachen nach der Sitzungs-ID suchen, prüfen Sie, ob die Sitzungs-ID korrekt ist.
API_NICHT_VERFÜGBAR Die Play Feature Delivery Library wird auf dem aktuellen Gerät nicht unterstützt. Das heißt, das Gerät kann keine Dateien herunterladen und installieren. Funktionen auf Abruf verfügbar. 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. Nutzer auffordern, eine Netzwerkverbindung herzustellen oder zu einem anderen Netzwerk 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 Module enthält, App hat bereits angefragt oder warten, bis alle aktuell angeforderten Module verfügbar sind um die Installation abzuschließen, bevor Sie die Anfrage wiederholen.

Wenn Sie ein Modul anfordern, nicht durch einen Fehler behebt.

SERVICE_DIED Der für die Verarbeitung der Anfrage zuständige Dienst ist inaktiv. Wiederholen Sie die Anfrage.

Dein SplitInstallStateUpdatedListener erhält ein SplitInstallSessionState mit diesem Fehlercode, Status FAILED und Sitzungs-ID -1.

INSUFFICIENT_STORAGE Auf dem Gerät ist nicht genügend freier Speicherplatz vorhanden, um die Funktion zu installieren. -Modul. Nutzer informieren, dass nicht genügend Speicherplatz für die Installation vorhanden ist .
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR SplitCompat konnte das Funktionsmodul nicht laden. Diese Fehler sollten nach der nächsten App automatisch behoben werden. neu starten.
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 daher nicht heruntergeladen. 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). Wenn Sie weitere Unterstützung benötigen, können Sie auch einen Hilfe-Link angeben, der leitet die Nutzenden zur Google Play-Hilfe

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.

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.
        }
    }
}

Die möglichen Status für Ihre Installationsanfrage sind in der folgenden Tabelle beschrieben.

Anfragestatus Beschreibung Vorgeschlagene Maßnahme
AUSSTEHEND Die Anfrage wurde akzeptiert und der Download sollte bald starten. UI-Komponenten wie eine Fortschrittsanzeige initialisieren um dem Nutzer Feedback zum Download zu geben.
REQUIRES_USER_CONFIRMATION Der Download erfordert eine Nutzerbestätigung. Am häufigsten tritt dieser Status auf, wenn die App nicht über Google Play Fordern Sie den Nutzer auf, 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 Sie eine Fortschrittsanzeige für den Download bereitstellen, verwenden Sie SplitInstallSessionState.bytesDownloaded() und SplitInstallSessionState.totalBytesToDownload() Methoden zum Aktualisieren der Benutzeroberfläche verwenden (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 des Funktionsmoduls Ressourcen.
Installation... Das Modul wird gerade auf dem Gerät installiert. Aktualisieren Sie die Fortschrittsanzeige. Dieser Status ist in der Regel kurz.
INSTALLIERT Das Modul ist auf dem Gerät installiert. Auf Code und Ressourcen im Modul zugreifen um die User Journey fortzusetzen.

Wenn das Modul für eine Android Instant App mit Android 8.0 (API-Level 26) bestimmt ist oder höher müssen Sie splitInstallHelper verwenden, App-Komponenten mit dem neuen Modul aktualisieren.

FEHLER Die Anfrage ist fehlgeschlagen, bevor das Modul auf dem Gerät installiert ist. Fordere den Nutzer auf, die Anfrage zu wiederholen oder abzubrechen.
WIRD ABGEBROCHEN Die Anfrage wird gerade vom Gerät abgebrochen. Weitere Informationen finden Sie im Abschnitt zur Installationsanfrage abbrechen.
GESTRICHEN Die Anfrage wurde abgebrochen.

Nutzerbestätigung einholen

In einigen Fällen kann in Google Play eine Nutzerbestätigung erforderlich sein, bevor ein Downloadanfrage. Beispiel: Ihre App wurde nicht von Google installiert. oder wenn du versuchst, einen großen Download über mobile Daten zu starten. 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:

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);
    }
    ...
 }

Sie können einen Launcher für Aktivitätsergebnisse über die integrierte ActivityResultContracts.StartIntentSenderForResult Vertrag. Siehe Aktivitätsergebnis-APIs.

Der Status der Anfrage wird abhängig von der Nutzerantwort aktualisiert:

  • Wenn der Nutzer die Bestätigung akzeptiert, ändert sich der Anfragestatus in PENDING und der Download wird fortgesetzt.
  • Lehnt der Nutzer die Bestätigung ab, ändert sich der Anfragestatus zu CANCELED
  • Wenn der Nutzer vor dem Löschen des Dialogfelds keine Auswahl trifft, bleibt der Anfragestatus REQUIRES_USER_CONFIRMATION. Ihre App kann den Nutzer noch einmal auffordern, die Anfrage abzuschließen.

Um einen Rückruf mit der Antwort des Nutzers zu erhalten, kannst du den Parameter ActivityResultCallback (siehe unten).

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.
        }
    });

Installationsanfrage abbrechen

Wenn Ihre Anwendung eine Anfrage vor der Installation abbrechen muss, kann sie cancelInstall()-Methode mithilfe der Sitzungs-ID der Anfrage (siehe unten).

Kotlin

splitInstallManager
    // Cancels the request for the given session ID.
    .cancelInstall(mySessionId)

Java

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 hat keinen Zugriff auf die Ressourcen des Moduls für System-UI-Komponenten, wie Benachrichtigungen. Wenn Sie solche Ressourcen sofort benötigen, sollten Sie und in das Basismodul Ihrer App einfügen.

SplitCompat aktivieren

Damit Ihre App über ein heruntergeladenes Modul auf Code und Ressourcen zugreifen kann, müssen Sie SplitCompat nur mit einer der Methoden aktivieren, die im folgenden Abschnitten.

Nachdem Sie SplitCompat für Ihre App aktiviert haben, müssen Sie auch SplitCompat aktivieren. für jede Aktivität in den von Ihnen auf die Ihre App Zugriff haben 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 zur Laufzeit in bestimmten Aktivitäten oder Diensten aktivieren. Diese Aktivierung von SplitCompat ist erforderlich, um Aktivitäten zu starten, die in Funktionsmodule. Überschreiben Sie dazu attachBaseContext wie unten dargestellt.

Wenn Sie eine benutzerdefinierte Application-Klasse haben, stattdessen erweitern können, SplitCompatApplication um SplitCompat für Ihre App zu aktivieren:

Kotlin

class MyApplication : SplitCompatApplication() {
    ...
}

Java

public class MyApplication extends SplitCompatApplication {
    ...
}

SplitCompatApplication überschreibt einfach ContextWrapper.attachBaseContext() um SplitCompat.install(Context applicationContext) einzuschließen. Wenn Sie keine möchten, dass Ihr Application-Kurs SplitCompatApplication erweitern, können Sie die attachBaseContext() überschreiben manuell:

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);
}

Wenn Ihr On-Demand-Modul kompatibel ist können Sie SplitCompat aufrufen, bedingt:

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);
    }
}

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:

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);
}

Auf in Funktionsmodulen definierte Komponenten zugreifen

Eine in einem Funktionsmodul definierte Aktivität starten

Sie können in Funktionsmodulen definierte Aktivitäten starten: startActivity() nachdem Sie SplitCompat aktiviert haben.

Kotlin

startActivity(Intent()
  .setClassName("com.package", "com.package.module.MyActivity")
  .setFlags(...))

Java

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.

Einen in einem Funktionsmodul definierten Dienst starten

Sie können Dienste, die in Funktionsmodulen definiert sind, mit startService() nachdem Sie SplitCompat aktiviert haben.

Kotlin

startService(Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...))

Java

startService(new Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...));

In einem Funktionsmodul definierte Komponente exportieren

Exportierte Android-Komponenten sollten nicht in optionale Module aufgenommen werden.

Das Build-System führt Manifesteinträge für alle Module im Basismodul zusammen. Wenn ein optionales Modul eine exportierte Komponente enthält, noch vor der Installation des Moduls und kann aufgrund von fehlendem Code zu Abstürzen führen. wenn er von einer anderen App aufgerufen wird.

Für interne Komponenten ist dies kein Problem, Es wird nur auf sie zugegriffen von der App aus, damit sie Prüfen Sie, ob das Modul installiert ist, bevor Sie auf das Modul zugreifen. Komponente.

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 interne Komponente über ein Intent, Intent aus der Aufrufer-App weiterleiten. Ist das Modul nicht vorhanden, Komponente das Modul herunterladen oder eine entsprechende Fehlermeldung an den Anrufer-App.

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.

Auf Code aus einem anderen Modul zugreifen

Über ein Modul auf Basiscode zugreifen

Code, der sich in Ihrem Basismodul befindet, 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 innerhalb eines Moduls kann nicht statisch von einem anderen aus zugegriffen werden aber nur indirekt über Reflexion aufgerufen werden kann.

Sie sollten wegen der Leistungskosten mit Bedacht dabei sein, wie oft dies geschieht der Reflexion. 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:

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();

Auf Ressourcen und Assets aus einem anderen Modul zugreifen

Sobald ein Modul installiert ist, können Sie auf Ressourcen und Assets im Standardmethode verwenden. 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, mit dem auf die Ressource verwiesen wird, ist der 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 versucht, auf die Ressourcen zuzugreifen, aktualisiert werden. 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 per On-Demand-Bereitstellung in eine App laden

Wir empfehlen die Verwendung von ReLinker, um alle native Bibliotheken, wenn Sie die On-Demand-Bereitstellung von Funktionsmodulen nutzen. ReLinker behebt ein Problem beim Laden nativer Bibliotheken nach der Installation eines Funktionsmodul. 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: Bei Instant-Apps sollten Sie diese spezielle Methode verwenden.

Wenn Sie den nativen Code und den nativen Code mit System.loadLibrary() laden 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 Bibliothek zu laden, die in einem optional ist, funktioniert es 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. Aber ein neuer Kontext tut dies. Dies lässt sich zum Beispiel mit 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();
        }
    }
}

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 erkennt die App den Code des Moduls noch nicht. und Ressourcen. Nachdem Sie die Metadaten der App aktualisiert haben, sollten Sie die des nächsten Hauptthread-Ereignisses durch Aufrufen eines neuen Handler, wie unten gezeigt:

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();
                        ...
                    }
                });
            }
        }
    }
}

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:

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”);
                ...
        }
    }
}

Bekannte Einschränkungen

  • Es ist nicht möglich, Android WebView in einer Aktivität zu verwenden, bei der auf Ressourcen oder Assets aus einem optionalen Modul. Das liegt an einer Inkompatibilität 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. Das Caching solcher Objekte könnte zum Absturz der App führen wenn ein Funktionsmodul installiert wird.

Installierte Module verwalten

So prüfen Sie, welche Funktionsmodule derzeit auf dem Gerät installiert sind: kannst du anrufen SplitInstallManager.getInstalledModules(), gibt ein Set<String> der Namen der installierten Module zurück, wie hier gezeigt. unten.

Kotlin

val installedModules: Set<String> = splitInstallManager.installedModules

Java

Set<String> installedModules = splitInstallManager.getInstalledModules();

Module deinstallieren

Sie können die Deinstallation von Modulen durch den Aufruf SplitInstallManager.deferredUninstall(List<String> moduleNames), wie unten dargestellt.

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"));

Die Deinstallation des Moduls erfolgt nicht sofort. Das heißt: werden sie im Hintergrund deinstalliert, 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

Mit App Bundles laden Geräte nur den Code und die Ressourcen herunter, die sie die für die Ausführung Ihrer App erforderlich sind. Für Sprachressourcen lädt das Gerät eines Nutzers Nur die Sprachressourcen deiner App, die in einer oder mehreren Sprachen aktuell sind die Sie in den Geräteeinstellungen ausgewählt haben.

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. Das Verfahren ähnelt dem ein Funktionsmodul herunterladen (siehe unten).

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);

Die Anfrage wird wie eine Anfrage für ein Funktionsmodul behandelt. Das heißt: können Sie wie gewohnt den Anfragestatus überwachen.

Wenn Ihre App die zusätzlichen Sprachressourcen nicht sofort benötigt, Die Installation kann verzögert werden, wenn die App im Hintergrund ausgeführt wird (siehe Abbildung). unten.

Kotlin

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

Java

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

Auf heruntergeladene Sprachressourcen zugreifen

Um Zugriff auf heruntergeladene Sprachressourcen zu erhalten, muss deine App den Methode SplitCompat.installActivity() innerhalb der Methode attachBaseContext() jeder Aktivität, die Zugriff auf diese Ressourcen benötigt (siehe unten).

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);
}

Für jede Aktivität, die Sie von Ihrer App heruntergeladen haben, Basiskontext aktualisieren und eine neue Sprache über die 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);
}

Damit diese Änderungen wirksam werden, müssen Sie Ihre Aktivität neu erstellen sobald die neue Sprache installiert und einsatzbereit ist. Sie können die Activity#recreate()-Methode.

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();
  ...
}

Zusätzliche Sprachressourcen deinstallieren

Ähnlich wie bei Funktionsmodulen können Sie zusätzliche Ressourcen unter folgendem Link deinstallieren: jederzeit ändern. Bevor Sie eine Deinstallation anfordern, sollten Sie zunächst ermitteln, Sprachen installiert sind:

Kotlin

val installedLanguages: Set<String> = splitInstallManager.installedLanguages

Java

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

Du kannst dann mithilfe der deferredLanguageUninstall()-Methode, wie unten gezeigt.

Kotlin

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

Java

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

Modulinstallationen lokal testen

Mit der Play Feature Delivery Library können Sie lokal testen, ob Ihre App die folgenden Aufgaben erfüllt: ohne eine Verbindung zum Play Store herzustellen:

Auf dieser Seite wird beschrieben, wie Sie die aufgeteilten APKs Ihrer App auf Ihrem Testgerät bereitstellen, damit dass Play Feature Delivery diese APKs automatisch verwendet, um Anfragen, Downloads und Module aus dem Play Store installieren.

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. Du benötigst bundletool, um einen neuen Satz installierbarer APKs aus dem Set.

APKs erstellen

Erstellen Sie die aufgeteilten APKs Ihrer App wie folgt, falls Sie dies noch nicht getan haben:

  1. Erstellen Sie mit einer der folgenden Methoden ein App-Bundle für Ihre App: <ph type="x-smartling-placeholder">
  2. 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
      --output my_app.apks
    

Das Flag --local-testing enthält Metadaten in der offenkundig ist, informiert die Play Feature Delivery Library darüber, dass die lokalen aufgeteilten APKs zum Testen verwendet werden sollen ohne Verbindung zum Play Store zu installieren.

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 auf den lokalen Speicher Ihres Geräts hochladen. Beide Aktionen können Sie mit der folgenden Befehl:

bundletool install-apks --apks my_app.apks

Wenn Sie jetzt Ihre App starten und den User Flow zum Herunterladen und Installieren abschließen Funktionsmodul ist, verwendet die Play Feature Delivery Library die APKs, die bundletool in den lokalen Speicher des Geräts übertragen werden.

Netzwerkfehler simulieren

Um Modulinstallationen aus dem Play Store zu simulieren, verwendet die Play Feature Delivery Library eine zur SplitInstallManager, mit der 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 der API-Aufrufe 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:

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);