Konfigurowanie wyświetlania na żądanie

Moduły funkcji pozwalają oddzielić niektóre funkcje i zasoby z modułu podstawowego aplikacji i uwzględnij je w pakiecie aplikacji. Do (w ramach Play Feature Delivery) użytkownicy mogą na przykład pobrać i zainstalować te funkcje na żądanie, gdy użytkownicy zainstalują już podstawowy plik APK Twojej aplikacji.

Weźmy na przykład aplikację do obsługi SMS-ów, która oferuje funkcje Przechwytywanie i wysyłanie wiadomości graficznych, ale tylko niewielki odsetek użytkowników wysyłać wiadomości graficzne. Warto dodać wiadomości obrazkowe jako który możesz pobrać. Dzięki temu początkowe pobranie aplikacji będzie mniejsze niż u wszystkich użytkowników. Tylko ci, którzy wysyłają wiadomości, muszą i pobrać ten dodatkowy komponent.

Pamiętaj, że ten typ modularyzacji wymaga większego wysiłku, a potencjalnie do refaktoryzacji istniejącego kodu aplikacji, więc dobrze się zastanów, który określonych funkcji aplikacji najlepiej byłoby, gdyby były dostępne dla użytkowników na żądanie. Aby lepiej zrozumieć optymalne przypadki użycia i wytyczne dotyczące funkcji na żądanie, przeczytaj sprawdzone metody dotyczące wygody użytkownika w zakresie wyświetlania na żądanie.

Jeśli chcesz stopniowo dzielić funkcje aplikacji na moduły w miarę upływu czasu, bez włączenie zaawansowanych opcji dostarczania, takich jak dostarczanie na żądanie, skonfigurować dostawę w czasie instalacji.

Ta strona pomoże Ci dodać moduł funkcji do projektu aplikacji oraz skonfigurować ją pod kątem wyświetlania na żądanie. Zanim zaczniesz, upewnij się, używasz Android Studio 3.5 lub nowszego i wtyczki Androida do obsługi Gradle w wersji 3.5.0. lub wyższą.

Konfigurowanie nowego modułu pod kątem wyświetlania na żądanie

Najłatwiejszym sposobem utworzenia nowego modułu funkcji jest użycie Android Studio 3.5 lub nowszy, Ponieważ moduły funkcji mają jest uzależniona od podstawowego modułu aplikacji, można go dodać tylko do istniejącego projekty aplikacji.

Aby dodać moduł funkcji do projektu aplikacji za pomocą Android Studio: wykonaj następujące czynności:

  1. Otwórz projekt aplikacji w IDE.
  2. Wybierz Plik > Nowe > Nowy moduł na pasku menu.
  3. W oknie Create New Module (Utwórz nowy moduł) wybierz Dynamic Feature Module (Moduł funkcji dynamicznych) i kliknij Next (Dalej).
  4. W sekcji Skonfiguruj nowy moduł wykonaj :
    1. Wybierz Podstawowy moduł aplikacji na potrzeby projektu aplikacji menu.
    2. Wypełnij pole Nazwa modułu. IDE używa tej nazwy do zidentyfikowania jako podprojektu Gradle w Plik ustawień Gradle. Gdy aby utworzyć pakiet aplikacji, Gradle używa ostatniego elementu podprojektu nazwa w celu wstawienia atrybutu <manifest split> w plik manifestu modułu funkcji.
    3. Podaj nazwę pakietu modułu. Domyślnie Android Studio sugeruje nazwę pakietu, która łączy nazwę pakietu głównego i nazwę modułu określoną w poprzednim kroku.
    4. Wybierz Minimalny poziom interfejsu API, który ma być obsługiwany przez moduł. Ta wartość powinna być zgodna z wartością modułu podstawowego.
  5. Kliknij Dalej.
  6. W sekcji Opcje pobierania modułu wykonaj te czynności:

    1. Określ Tytuł modułu za pomocą maksymalnie 50 znaków. Platforma wykorzysta go do identyfikacji modułu wśród użytkowników, jeśli na przykład i potwierdź, czy użytkownik chce pobrać moduł. Do tego celu dlatego podstawowy moduł aplikacji musi zawierać tytuł string resource, co potrafi tłumaczyć. Przy tworzeniu modułu w Android Studio IDE doda zasób łańcuchowy do modułu podstawowego i wstrzykuje makro następujący wpis w pliku manifestu modułu funkcji:

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. W menu w sekcji Uwzględnianie podczas instalacji wybierz Nie uwzględniaj moduł w momencie instalacji. Android Studio wstawia zgodnie z Twoim wyborem w pliku manifestu modułu:

      <dist:module ... >
        <dist:delivery>
            <dist:on-demand/>
        </dist:delivery>
      </dist:module>
      
    3. Zaznacz pole Fusing, aby ten moduł był dostępny. na urządzeniach z Androidem 4.4 (poziom interfejsu API 20) lub starszym z wieloma plikami APK. Oznacza to, że możesz włączyć w tym module działanie na żądanie i wyłącz fusing, aby pominąć ją na urządzeniach, które nie obsługują pobieranie i instalowanie dzielonych pakietów APK. Android Studio wstawia zgodnie z Twoim wyborem w pliku manifestu modułu:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. Kliknij Zakończ.

Gdy Android Studio zakończy tworzenie modułu, sprawdź jego zawartość w panelu Projekt (wybierz Widok > Okna narzędziowe > Projekt) na pasku menu). Domyślnym kodem, zasobami i organizacją powinny być jak w standardowym module aplikacji.

Następnie trzeba wdrożyć funkcję instalacji na żądanie przy użyciu biblioteki Play Feature Delivery.

Dołącz do projektu bibliotekę Play Feature Delivery

Najpierw musisz dodać bibliotekę Play Feature Delivery do projektu.

Poproś o moduł na żądanie

Gdy aplikacja musi użyć modułu funkcji, może poprosić o jego użycie, znajduje się na pierwszym planie przez SplitInstallManager zajęcia. Podczas tworzenia aplikacja musi określić nazwę modułu zdefiniowaną przez tag split w pliku manifestu modułu docelowego. Gdy utwórz moduł funkcji w Android Studio system kompilacji używa podanej przez Ciebie nazwy modułu. , aby wstawić tę właściwość do pliku manifestu modułu podczas kompilacji. Aby dowiedzieć się więcej, przeczytaj plików manifestu modułu funkcji.

Weźmy na przykład aplikację z modułem na żądanie, który umożliwia robienie i wysyłanie zdjęć wiadomości obrazkowe za pomocą aparatu urządzenia, oraz moduł na żądanie określa split="pictureMessages" w swoim manifeście. ten przykładowy kod wykorzystuje pole SplitInstallManager do żądania pictureMessages (wraz z dodatkowym modułem na niektóre filtry promocyjne):

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

Gdy aplikacja prosi o moduł na żądanie, biblioteka Play Feature Delivery wykorzystuje strategia „ogień i zapomnij”. Oznacza to, że wysyła żądanie pobrania z modułem do platformy, ale nie monitoruje instalacji udało się. Aby przenieść użytkownika do przodu po lub bezproblemowo je obsługiwać, pamiętaj, aby śledzić żądania stanu.

Uwaga: możesz poprosić o moduł funkcji już zainstalowany na urządzeniu. Interfejs API natychmiast uznaje żądanie za ukończone, jeśli wykryje moduł Zainstalowano. Poza tym po zainstalowaniu modułu Google Play aktualizuje go. automatycznie. To oznacza, że gdy prześlesz nową wersję pakietu aplikacji, platforma aktualizuje wszystkie zainstalowane pliki APK należące do Twojej aplikacji. Więcej informacji: Zarządzanie aktualizacjami aplikacji

Aby mieć dostęp do kodu i zasobów modułu, aplikacja musi: włącz SplitCompat. Pamiętaj, że narzędzie SplitCompat nie wymagane w przypadku aplikacji błyskawicznych na Androida.

Odrocz instalację modułów na żądanie

Jeśli nie potrzebujesz aplikacji do natychmiastowego pobierania i instalowania wersji na żądanie , możesz opóźnić instalację, gdy aplikacja działa w tle. Dla: np. gdy chcesz wstępnie załadować materiały promocyjne do późniejszego udostępnienia do aplikacji.

Możesz wskazać moduł do pobrania później za pomocą polecenia deferredInstall() Jak pokazano poniżej. A w przeciwieństwie do SplitInstallManager.startInstall(), aplikacja nie musi być na pierwszym planie, by zainicjować żądanie odroczoną instalację.

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

Prośby o odroczone instalacje są najlepszym rozwiązaniem – nie można śledzić ich postęp. Zanim spróbujesz uzyskać dostęp do modułu określonego dla odroczonego musisz sprawdź, czy moduł został zainstalowany. Jeśli wymaga, aby moduł był dostępny od razu, zamiast SplitInstallManager.startInstall(), aby poprosić o ten identyfikator, tak jak poprzednio .

Monitorowanie stanu żądania

Aby móc aktualizować pasek postępu, uruchom intencję po lub bezproblemowo obsłużyć błąd żądania, musisz nasłuchiwać aktualizacje stanu z asynchronicznego zadania SplitInstallManager.startInstall(). Zanim zaczniesz otrzymywać aktualizacje dotyczące prośby o instalację, zarejestruj detektor i uzyskać identyfikator sesji żądania, jak pokazano poniżej.

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

Obsługa błędów żądań

Pamiętaj, że instalacja modułów funkcji na żądanie może czasami się nie udać, tak jak instalacja aplikacji nie zawsze się kończy. Przyczyny niepowodzenia instalacji z małą ilością pamięci na urządzeniu, brakiem połączenia sieciowego lub brakiem możliwości zalogować się w Sklepie Google Play. Sugestie dotyczące postępowania w takich sytuacjach z perspektywy użytkownika zapoznaj się Wskazówki dotyczące UX w zakresie wyświetlania na żądanie.

Jeśli chodzi o kod, należy radzić sobie z błędami pobierania lub instalowania modułu. przy użyciu addOnFailureListener() w następujący sposób:

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

W tabeli poniżej znajdziesz stany błędów, które mogą być konieczne przez aplikację:

Kod błędu Opis Sugerowane działanie
AKTYWNE_SESSIONS_LIMIT_PRZEKROCZONO Żądanie zostało odrzucone, ponieważ istnieje co najmniej jeden aktualnie pobieranego żądania. Sprawdź, czy są jakieś żądania, które są nadal pobierane. w powyższym przykładzie.
MODULE_NIEDOSTĘPNY Google Play nie może znaleźć żądanego modułu na podstawie w aktualnie zainstalowanej wersji aplikacji, na urządzeniu i w Google Play użytkownika koncie. Jeśli użytkownik nie ma dostępu do modułu, powiadom go o tym.
NIEPRAWIDŁOWE_ŻĄDANIE Google Play otrzymało żądanie, które jednak jest nieprawidłowy. Sprawdź, czy informacje zawarte w prośbie jest kompletna i dokładna.
SESJA_NIE ZNALEZIONO Nie znaleziono sesji o podanym identyfikatorze. Jeśli próbujesz monitorować stan żądania według identyfikatora sesji, sprawdź, czy jest on prawidłowy.
API_NOT_AVAILABLE (niedostępny) Biblioteka Play Feature Delivery nie jest obsługiwana na obecnym urządzeniu. Oznacza to, że urządzenia nie można pobrać ani zainstalować. funkcje na żądanie. W przypadku urządzeń z Androidem 4.4 (poziom interfejsu API 20) lub starszym uwzględnij moduły funkcji podczas instalacji za pomocą Właściwość pliku manifestu dist:fusing. Aby dowiedzieć się więcej, przeczytaj o plik manifestu modułu funkcji.
BŁĄD_SIECI Żądanie nie zostało zrealizowane z powodu błędu sieci. Poproś użytkownika o nawiązanie połączenia sieciowego lub zmień sieć.
ODRZUCONO Aplikacja nie może zarejestrować żądania z powodu niewystarczających uprawnień. Zwykle dzieje się tak, gdy aplikacja działa w tle. Ponów próbę, gdy aplikacja wróci na pierwszy plan.
NIEZGODNE_Z_ISTNIEJĄCĄ_SESJĄ Żądanie zawiera co najmniej jeden moduł, który został już żądania, ale nie zostały jeszcze zainstalowane. Utwórz nowe żądanie, które nie będzie zawierać modułów, które aplikacja już wysłała żądanie lub poczekaj na wszystkie aktualnie żądane moduły dokończ instalację i spróbuj ponownie wysłać żądanie.

Pamiętaj, że żądanie modułu, który został już i nie powoduje błędu.

WYKONANY_USŁUGA Usługa odpowiedzialna za obsługę tego żądania nie działa. Spróbuj ponownie.

SplitInstallStateUpdatedListener otrzymuje SplitInstallSessionState z tym kodem błędu, stanem FAILED i identyfikator sesji -1.

ZA MAŁO_MIEJSCA Na urządzeniu nie ma wystarczającej ilości wolnego miejsca, aby zainstalować tę funkcję . Powiadom użytkownika, że nie ma wystarczającej ilości miejsca na dane do zainstalowania funkcji.
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_CONTENT_ERROR, SplitCompat nie może wczytać modułu funkcji. Te błędy powinny zniknąć automatycznie po następnej aplikacji zrestartować.
NIE ZNALEZIONO SKLEPU PLAY Aplikacja Sklep Play nie jest zainstalowana na urządzeniu. Poinformuj użytkownika, że do pobrania tej aplikacji wymagana jest aplikacja Sklep Play funkcji.
APLIKACJA_NIE_DOSTĘPNA Ta aplikacja nie została zainstalowana z Google Play i nie można użyć tej funkcji pobrano. Ten błąd może występować tylko w przypadku odroczonych instalacji. Jeśli chcesz, aby użytkownik pozyskał aplikację z Google Play, użyj startInstall(), który może uzyskać niezbędne potwierdzenie użytkownika.
INTERNAL_ERROR W Sklepie Play wystąpił błąd wewnętrzny. Spróbuj ponownie.

Jeśli użytkownik poprosi o pobranie modułu na żądanie i wystąpi błąd, rozważ wyświetlenie okna z 2 opcjami: Wypróbuj (co powoduje ponowną próbę przesłania żądania) i Cancel (Anuluj), ). Aby uzyskać dodatkową pomoc, podaj również link do Pomocy, który: kieruje użytkowników do Centrum pomocy Google Play.

Aktualizacje stanu uchwytu

Gdy zarejestrujesz detektor i zapiszesz identyfikator sesji dla swojego żądania, użyj StateUpdatedListener.onStateUpdate() do obsługi zmian stanu, jak pokazano poniżej.

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

Możliwe stany prośby o instalację zostały opisane w tabeli poniżej.

Stan żądania Opis Sugerowane działanie
OCZEKUJĄCA Prośba została zaakceptowana, a pobieranie powinno się wkrótce rozpocząć. zainicjuj komponenty interfejsu, np. pasek postępu, aby przekazać użytkownikom opinię o pobieranym pliku.
REQUIRES_USER_CONFIRMATION Pobranie wymaga potwierdzenia przez użytkownika. Ten stan występuje najczęściej, jeśli aplikacja nie została zainstalowana za pomocą Google Play. Wyświetlaj użytkownikowi prośbę o potwierdzenie pobrania funkcji w Google Play. Więcej informacji znajdziesz w sekcji uzyskać potwierdzenie użytkownika.
POBIERANIE Trwa pobieranie. Jeśli udostępniasz pasek postępu pobierania, użyj SplitInstallSessionState.bytesDownloaded() i SplitInstallSessionState.totalBytesToDownload() do aktualizacji interfejsu użytkownika (zobacz przykładowy kod nad tą tabelą).
POBRANE Moduł został pobrany na urządzenie, ale instalacja jeszcze się nie rozpoczęła. Aplikacje powinny włączyć funkcję SplitCompat aby mieć dostęp do pobranych modułów i uniknąć wyświetlania tego stanu. Jest to wymagane, aby uzyskać dostęp do kodu modułu funkcji i i zasobami Google Cloud.
INSTALUJĘ Urządzenie instaluje moduł. Zaktualizuj pasek postępu. Ten stan jest zwykle krótki.
ZAINSTALOWANO Moduł jest zainstalowany na urządzeniu. Kod dostępu i zasób w module i podejmować kolejne działania.

Jeśli moduł dotyczy aplikacji błyskawicznej na Androida uruchomionej na Androidzie 8.0 (poziom interfejsu API 26) lub wyższej, musisz użyć funkcji splitInstallHelper, zaktualizuj komponenty aplikacji za pomocą nowego modułu.

BŁĄD Żądanie nie powiodło się, zanim moduł został zainstalowanej na urządzeniu. Poproś użytkownika o ponowne przesłanie prośby lub jej anulowanie.
ANULuję Trwa anulowanie żądania na urządzeniu. Więcej informacji znajdziesz w sekcji Anuluj prośbę o instalację.
ODWOŁANY Prośba została anulowana.

Uzyskiwanie potwierdzenia użytkownika

W niektórych przypadkach Google Play może wymagać potwierdzenia przez użytkownika przed spełnieniem warunków aby je pobrać. Jeśli na przykład Twoja aplikacja nie została zainstalowana przez Google graj lub jeśli próbujesz pobrać dużą ilość treści przez mobilną transmisję danych. W takich przypadkach stan żądania REQUIRES_USER_CONFIRMATION, a aplikacja musi uzyskać potwierdzenie od użytkownika, zanim urządzenie będzie mogło pobrać zainstalować moduły z żądania. Aby uzyskać potwierdzenie, aplikacja powinna wyświetlić użytkownikowi następujący komunikat:

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

Możesz zarejestrować program uruchamiający wyniki aktywności, używając wbudowanego ActivityResultContracts.StartIntentSenderForResult umowy. Zapoznaj się z artykułem Interfejsy API wyników działań.

Stan żądania jest aktualizowany w zależności od odpowiedzi użytkownika:

  • Jeśli użytkownik zaakceptuje potwierdzenie, stan prośby zmieni się na PENDING i rozpocznie się pobieranie.
  • Jeśli użytkownik odmówi potwierdzenia, stan prośby zmieni się na CANCELED
  • Jeśli użytkownik nie dokona wyboru przed zniszczeniem okna, stan prośby pozostanie bez zmian: REQUIRES_USER_CONFIRMATION. Aplikacja może ponownie poprosić użytkownika o wykonanie tego żądania.

Aby otrzymać wywołanie zwrotne z odpowiedzią użytkownika, możesz zastąpić parametr ActivityResultCallback, tak jak poniżej.

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

Anulowanie prośby o instalację

Jeśli aplikacja musi anulować żądanie przed zainstalowaniem, może wywołać funkcję cancelInstall() za pomocą identyfikatora sesji żądania, jak pokazano poniżej.

Kotlin

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

Java

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

Dostęp do modułów

Aby uzyskać dostęp do kodu i zasobów z pobranego modułu po jego pobraniu, musi włączyć Biblioteka SpitCompat zarówno dla aplikacji, jak i dla poszczególnych działań w modułach funkcji aplikacji pobierania.

Trzeba jednak pamiętać, że platforma ma następujące problemy: dostęp do zawartości modułu przez pewien czas (dni, przypadków) po pobraniu modułu:

  • Platforma nie może stosować żadnych nowych wpisów manifestu wprowadzonych przez moduł.
  • Platforma nie ma dostępu do zasobów modułu dotyczących komponentów UI systemu, takich jak powiadomienia. Jeśli musisz natychmiast skorzystać z tych zasobów, łącznie z tymi zasobami w module podstawowym aplikacji.

Włącz SplitCompat

Aby aplikacja miała dostęp do kodu i zasobów z pobranego modułu, musisz włączyć SplitCompat, używając tylko jednej z metod opisanych w poniższych sekcji.

Po włączeniu SplitCompat w swojej aplikacji musisz też włączyć SplitCompat dla każdego działania w modułach funkcji, do których aplikacja ma mieć dostęp.

Zadeklaruj SplitCompatApplication w pliku manifestu

Najprostszym sposobem włączenia narzędzia SplitCompat jest zadeklarowanie parametru SplitCompatApplication jako podklasa Application w klasach plik manifestu aplikacji, jak pokazano poniżej:

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

Gdy aplikacja zostanie zainstalowana na urządzeniu, będziesz mieć dostęp do kodu i zasobów z: które automatycznie pobierają moduły funkcji.

Wywołuj SplitCompat w czasie działania

Możesz też włączyć SplitCompat w przypadku określonych działań lub usług w czasie działania. Ten sposób włączenia SplitCompat jest wymagany do uruchamiania działań uwzględnionych w modułów funkcji. Aby to zrobić, zastąp attachBaseContext w sposób pokazany poniżej.

Jeśli masz niestandardową klasę Application, zamiast tego przedłuż SplitCompatApplication. aby włączyć SplitCompat dla swojej aplikacji, wykonując te czynności:

Kotlin

class MyApplication : SplitCompatApplication() {
    ...
}

Java

public class MyApplication extends SplitCompatApplication {
    ...
}

SplitCompatApplication po prostu zastępuje ContextWrapper.attachBaseContext() aby uwzględnić SplitCompat.install(Context applicationContext). Jeśli nie chcesz chcesz, aby zajęcia w Application rozszerzenie SplitCompatApplication, możesz zastąpić attachBaseContext() ręcznie w następujący sposób:

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

Jeśli Twój moduł na żądanie jest zgodny zarówno w przypadku aplikacji błyskawicznych, jak i zainstalowanych, można wywołać funkcję SplitCompat warunkowo w następujący sposób:

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

Włącz SplitCompat do działań w module

Po włączeniu SplitCompat dla aplikacji podstawowej musisz włączyć aplikację SplitCompat za każdą aktywność pobieraną przez aplikację w ramach modułu funkcji. Aby to zrobić: użyj metody SplitCompat.installActivity() w ten sposób:

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

Uzyskiwanie dostępu do komponentów zdefiniowanych w modułach funkcji

Rozpocznij ćwiczenie zdefiniowane w module funkcji

Działania zdefiniowane w modułach funkcji możesz uruchamiać za pomocą startActivity() po włączeniu narzędzia SplitCompat.

Kotlin

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

Java

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

Pierwszym parametrem setClassName jest nazwa pakietu aplikacji oraz parametr drugi parametr to pełna nazwa klasy aktywności.

W ćwiczeniu w module funkcji pobranym na żądanie musisz włącz w niej narzędzie SplitCompat.

Uruchom usługę zdefiniowaną w module funkcji

Usługi zdefiniowane w modułach funkcji możesz uruchamiać za pomocą startService() po włączeniu narzędzia SplitCompat.

Kotlin

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

Java

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

Eksportowanie komponentu zdefiniowanego w module funkcji

Wyeksportowanych komponentów Androida nie należy umieszczać w modułach opcjonalnych.

System kompilacji scala wpisy manifestu wszystkich modułów z modułem podstawowym. gdyby moduł opcjonalny zawierał wyeksportowany komponent, byłby dostępny nawet przed zainstalowaniem modułu i może spowodować awarię z powodu brakującego kodu. w przypadku wywołania z innej aplikacji.

Nie stanowi to problemu w przypadku komponentów wewnętrznych. są one dostępne tylko dla nich, przez aplikację, dzięki czemu może sprawdź, czy moduł jest zainstalowany przed uzyskaniem dostępu przez komponent.

Jeśli potrzebujesz wyeksportowanego komponentu i chcesz, by jego zawartość znalazła się w opcjonalnym , rozważ wdrożenie wzorca serwera proxy. Aby to zrobić, dodaj do bazy danych komponent wyeksportowany przez serwer proxy. po uzyskaniu dostępu komponent serwera proxy może sprawdzić, czy na stronie zawiera treść. Jeśli istnieje moduł, serwer proxy może uruchomić komponent wewnętrzny z modułu za pomocą interfejsu Intent, z aplikacji wywołującej intencję Jeśli moduł nie jest dostępny, funkcja może pobrać moduł lub zwrócić odpowiedni komunikat o błędzie do aplikacji rozmówcy.

Dostęp do kodu i zasobów z zainstalowanych modułów

Jeśli włączysz SplitCompat dla swojej bazy kontekstu aplikacji i działań w module funkcji, możesz użyć z modułu funkcji i zasobów, tak jakby były one częścią podstawowego pliku APK. po zainstalowaniu modułu opcjonalnego.

Kod dostępu z innego modułu

Uzyskiwanie dostępu do kodu podstawowego z modułu

Kod wewnątrz modułu podstawowego może być używany bezpośrednio przez inne moduły. Nie musisz robić nic szczególnego. po prostu zaimportuj i użyj odpowiednich zajęć.

Uzyskiwanie dostępu do kodu modułu z innego modułu

Obiekt lub klasa wewnątrz modułu nie może być statycznie dostępna z innego źródła ale można uzyskać do niego dostęp pośrednio dzięki odbiciu.

Należy uważać, jak często się to zdarza, ze względu na koszty wydajności. refleksji. W złożonych przypadkach używaj platform wstrzykiwania zależności, takich jak Dagger 2, aby zagwarantować jedno wywołanie refleksji na od początku śledzenia.

Aby uprościć interakcje z obiektem po utworzeniu wystąpienia, zalecamy zdefiniowanie interfejsu w module podstawowym i jego implementację z modułu funkcji. Przykłady:

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

Dostęp do zasobów z innego modułu

Po zainstalowaniu modułu możesz uzyskać dostęp do zasobów w w standardowy sposób z 2 zastrzeżeniami:

  • Jeśli uzyskujesz dostęp do zasobu z innego modułu, nie będzie on ma dostęp do identyfikatora zasobu, chociaż zasób wciąż może do którego uzyskano dostęp za pomocą nazwy. Pamiętaj, że pakiet, w którym chcesz odwołać się do zasobu, to pakietu modułu, w którym zdefiniowany jest zasób.
  • Jeśli chcesz uzyskać dostęp do zasobów, które znajdują się w nowo zainstalowanej aplikacji z innego zainstalowanego modułu Twojej aplikacji, musisz to zrobić za pomocą kontekstu aplikacji. Kontekst komponentu, który próbuje uzyskać dostęp do zasobów, nie zostanie jeszcze być aktualizowane. Możesz też ponownie utworzyć ten komponent (np. wywołać Activity.recreate()) lub Po module funkcji ponownie zainstaluj w niej SplitCompat. instalacji.

Wczytywanie kodu natywnego w aplikacji przy użyciu dostarczania na żądanie

Zalecamy użycie narzędzia ReLinker, aby wczytać wszystkie Twoich bibliotek natywnych podczas korzystania z modułów funkcji na żądanie. ReLinker rozwiązuje problem z wczytywaniem bibliotek natywnych po zainstalowaniu z modułu funkcji. Więcej informacji o narzędziu ReLinker znajdziesz w Wskazówki dotyczące JNI na Androidzie

Wczytywanie kodu natywnego z modułu opcjonalnego

Po zainstalowaniu podziału zalecamy wczytanie kodu natywnego przez ReLinker. W przypadku aplikacji błyskawicznych użyj tej specjalnej metody.

Jeśli do wczytywania kodu natywnego i natywnego używasz interfejsu System.loadLibrary() zależy od innej biblioteki w module, musisz ręcznie tę inną bibliotekę. Jeśli używasz narzędzia ReLinker, równoważna operacja to Relinker.recursively().loadLibrary()

Jeśli używasz dlopen() w kodzie natywnym do wczytywania biblioteki zdefiniowanej w opcjonalny, nie będzie działał ze względnymi ścieżkami biblioteki. Najlepszym rozwiązaniem jest pobranie ścieżki bezwzględnej biblioteki z kodu w Javie. przez usługę ClassLoader.findLibrary(), a potem użyj jej w rozmowie w usłudze dlopen(). Zrób to przed wpisaniem kodu natywnego lub użyj wywołania JNI z na język Java.

Dostęp do zainstalowanych aplikacji błyskawicznych na Androida

Gdy moduł aplikacji błyskawicznej na Androida zgłosi się jako INSTALLED, możesz uzyskać dostęp do jego kod i zasoby za pomocą odświeżonej aplikacji Kontekst O kontekst utworzony przez aplikację przed zainstalowaniem modułu (np. przechowywanej w zmiennej) nie zawiera treści nowego parametru . Można to jednak uzyskać za pomocą nowego kontekstu, np. 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();
        }
    }
}

Aplikacje błyskawiczne na Androida na Androida 8.0 lub nowszego

Gdy wysyłasz żądanie modułu na żądanie w aplikacji błyskawicznej na Androida na Androida 8.0 (poziom interfejsu API 26) lub wyższym, po zgłoszeniu żądania instalacji jako INSTALLED zaktualizować aplikację w kontekście nowego modułu, używając wywołania SplitInstallHelper.updateAppInfo(Context context) W przeciwnym razie aplikacja nie zna jeszcze kodu modułu. i zasobami. Po zaktualizowaniu metadanych aplikacji musisz załadować plik modułu podczas następnego zdarzenia głównego wątku, wywołując nowy element Handler, jak pokazano poniżej:

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

Wczytaj biblioteki C/C++

Jeśli chcesz wczytywać biblioteki C/C++ z modułu, który urządzenie już ma pobrane w aplikacji błyskawicznej, użyj SplitInstallHelper.loadLibrary(Context context, String libName), jak poniżej:

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

Znane ograniczenia

  • Nie można używać komponentu WebView Androida w aktywności, która uzyskuje dostęp z modułu opcjonalnego. Wynika to z niezgodności między WebView i SpllitCompat na Androidzie API na poziomie 28 lub niższym.
  • Nie możesz zapisywać w pamięci podręcznej obiektów ApplicationInfo z Androidem, ich zawartości ani które zawierają te obiekty w Twojej aplikacji. Te obiekty należy zawsze pobierać w razie potrzeby z kontekstu aplikacji. Buforowanie takich obiektów może spowodować awarię aplikacji podczas instalowania modułu funkcji.

Zarządzaj zainstalowanymi modułami

Aby sprawdzić, które moduły funkcji są obecnie zainstalowane na urządzeniu, Możesz zadzwonić SplitInstallManager.getInstalledModules(), , który zwraca Set<String> nazw zainstalowanych modułów, jak pokazano na ilustracji poniżej.

Kotlin

val installedModules: Set<String> = splitInstallManager.installedModules

Java

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

Odinstaluj moduły

Możesz zażądać od urządzenia odinstalowania modułów, wywołując SplitInstallManager.deferredUninstall(List<String> moduleNames), jak pokazano poniżej.

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

Odinstalowania modułu nie następują natychmiast. To znaczy, w razie potrzeby odinstalowuje je w tle, aby zaoszczędzić miejsce. Możesz potwierdzić, że urządzenie ma Użytkownik usunął moduł przez jego wywołanie SplitInstallManager.getInstalledModules() i sprawdzania wyników, jak opisano w poprzedniej sekcji.

Pobierz dodatkowe materiały dotyczące języków

Dzięki pakietom aplikacji urządzenia pobierają tylko kod i zasoby, które są wymagane do uruchomienia aplikacji. Aby znaleźć zasoby językowe, urządzenie użytkownika tylko zasoby językowe aplikacji, które są zgodne z co najmniej jednym obecnie językiem. wybraną w ustawieniach urządzenia.

Jeśli chcesz, aby aplikacja miała dostęp do zasobów językowych – na przykład Selektor języka w aplikacji można np. zaimplementować, korzystając z funkcji Play Feature Delivery do pobierania ich na żądanie z biblioteki. Proces ten jest podobny do procedury po pobraniu modułu funkcji, jak pokazano poniżej.

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

Żądanie jest obsługiwane tak, jakby było żądaniem modułu funkcji. To znaczy, możesz monitorować stan żądania w zwykły sposób.

Jeśli aplikacja nie wymaga od razu dodatkowych zasobów językowych, może opóźnić instalację, gdy aplikacja działa w tle, jak pokazano poniżej.

Kotlin

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

Java

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

Dostęp do pobranych zasobów językowych

Aby uzyskać dostęp do pobranych zasobów językowych, aplikacja musi uruchomić Metoda SplitCompat.installActivity() w metodzie attachBaseContext() każdej aktywności, która wymaga dostępu do tych zasobów, jak pokazano poniżej.

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

W przypadku każdej aktywności, w której chcesz korzystać z zasobów językowych pobranych przez aplikację, zaktualizować kontekst podstawowy i ustawić nowe ustawienia regionalne 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);
}

Aby te zmiany zaczęły obowiązywać, musisz odtworzyć swoją aktywność po zainstalowaniu nowego języka i gotowości do użycia. Za pomocą Metoda Activity#recreate().

Kotlin

when (state.status()) {
  SplitInstallSessionStatus.INSTALLED -> {
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate()
  }
  ...
}

Java

switch (state.status()) {
  case SplitInstallSessionStatus.INSTALLED:
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate();
  ...
}

Odinstaluj dodatkowe zasoby językowe

Podobnie jak w przypadku modułów funkcji dodatkowe zasoby możesz odinstalować na w dowolnym momencie. Przed wysłaniem prośby o odinstalowanie warto najpierw określić, języki są obecnie zainstalowane w następujący sposób.

Kotlin

val installedLanguages: Set<String> = splitInstallManager.installedLanguages

Java

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

Następnie wybierz języki, które chcesz odinstalować, deferredLanguageUninstall(), jak pokazano poniżej.

Kotlin

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

Java

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

Lokalne testowanie instalacji modułów

Biblioteka Play Feature Delivery pozwala lokalnie przetestować, czy aplikacja tych treści bez łączenia się ze Sklepem Play:

Na tej stronie dowiesz się, jak wdrożyć dzielone pliki APK aplikacji na urządzeniu testowym, że Play Feature Delivery automatycznie używa tych plików APK do symulowania żądania, pobierania i instalowanie modułów ze Sklepu Play.

Chociaż nie musisz wprowadzać żadnych zmian w logice aplikacji, musisz spełniasz te wymagania:

.

Tworzenie zestawu plików APK

Jeśli jeszcze go nie masz, utwórz dzielone pakiety APK swojej aplikacji w ten sposób:

  1. Utwórz pakiet aplikacji dla swojej aplikacji, korzystając z jednej z tych metod:
  2. Użyj funkcji bundletool, aby wygenerować zestaw Pliki APK na wszystkie urządzenia za pomocą tego polecenia:

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

Flaga --local-testing zawiera metadane w plikach APK wskazuje, że informuje bibliotekę Play Feature Delivery, że należy używać lokalnych podzielonych pakietów APK do testowania instalując moduły funkcji bez konieczności łączenia się ze Sklepem Play.

Wdrażanie aplikacji na urządzeniu

Gdy utworzysz zestaw plików APK przy użyciu flagi --local-testing, użyj bundletool, aby zainstalować podstawową wersję aplikacji i przenieść pliki APK w pamięci lokalnej urządzenia. Obie te czynności możesz wykonać za pomocą to polecenie:

bundletool install-apks --apks my_app.apks

Teraz po uruchomieniu aplikacji i postępowaniu użytkownika, aby ją pobrać i zainstalować, modułu funkcji, biblioteka Play Feature Delivery używa plików APK, które bundletool przeniesione do pamięci lokalnej urządzenia.

Symulowanie błędu sieci

Aby symulować instalacje modułów ze Sklepu Play, biblioteka Play Feature Delivery używa alternatywna dla funkcji SplitInstallManager, nazwana FakeSplitInstallManager, aby zażądać jego modułu. Gdy używasz pola bundletool z flagą --local-testing utworzenie zestawu plików APK i wdrożenie ich na urządzeniu testowym zawiera metadane informujące, że biblioteka Play Feature Delivery przełącza się automatycznie do wywoływania FakeSplitInstallManager przez interfejs API Twojej aplikacji, a nie SplitInstallManager.

FakeSplitInstallManager zawiera flagę wartości logicznej, którą możesz włączyć zasymulować błąd sieci, gdy następnym razem aplikacja poprosi o zainstalowanie modułu. Do dostęp do pakietu FakeSplitInstallManager w testach, możesz uzyskać jego instancję za pomocą FakeSplitInstallManagerFactory, jak poniżej:

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