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. Możesz dodać funkcję przesyłania wiadomości z obrazami jako pobierany moduł funkcji. 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 modułowości wymaga więcej pracy i możliwego przebudowania dotychczasowego kodu aplikacji. Dlatego dokładnie zastanów się, które z funkcji aplikacji najlepiej sprawdzą się w ramach funkcji na żądanie. Aby lepiej zrozumieć optymalne przypadki użycia i wskazówki dotyczące funkcji na żądanie, przeczytaj sprawdzone metody dotyczące wygody użytkownika w przypadku funkcji 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.
Na tej stronie możesz dodać moduł funkcji do projektu aplikacji i skonfigurować go do dostarczania na żądanie. Zanim zaczniesz, upewnij się, że używasz Android Studio 3.5 lub nowszej wersji oraz wtyczki Android Gradle 3.5.0 lub nowszej.
Konfigurowanie nowego modułu pod kątem wyświetlania na żądanie
Najłatwiej utworzyć nowy moduł funkcji za pomocą Android Studio 3.5 lub nowszej wersji. Ponieważ moduły funkcji są nieodłącznie zależne od modułu aplikacji podstawowej, możesz je dodawać tylko do istniejących projektów aplikacji.
Aby dodać moduł funkcji do projektu aplikacji za pomocą Android Studio:
- Otwórz projekt aplikacji w IDE.
- Wybierz Plik > Nowe > Nowy moduł na pasku menu.
- W oknie Create New Module (Utwórz nowy moduł) wybierz Dynamic Feature Module (Moduł funkcji dynamicznych) i kliknij Next (Dalej).
- W sekcji Skonfiguruj nowy moduł wykonaj
:
- Wybierz Podstawowy moduł aplikacji na potrzeby projektu aplikacji menu.
- Wypełnij pole Nazwa modułu. IDE używa tej nazwy do identyfikowania modułu jako podprojektu Gradle w pliku 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. - Podaj nazwę pakietu modułu. Domyślnie Android Studio sugeruje nazwę pakietu, która łączy nazwę pakietu głównego modułu podstawowego i nazwy modułu określonej w poprzednim kroku.
- Wybierz minimalny poziom interfejsu API, który ma obsługiwać moduł. Ta wartość powinna być zgodna z wartością modułu podstawowego.
- Kliknij Dalej.
W sekcji Opcje pobierania modułu wykonaj te czynności:
Określ Tytuł modułu za pomocą maksymalnie 50 znaków. Platforma używa tego tytułu, aby identyfikować moduł dla użytkowników, na przykład w celu potwierdzenia, czy użytkownik chce go pobrać. Z tego powodu moduł podstawowy aplikacji musi zawierać tytuł modułu jako zasób ciągu tekstowego, który możesz przetłumaczyć. Podczas tworzenia modułu w Android Studio IDE automatycznie dodaje do modułu podstawowego zasób ciągu znaków i wstrzykuje do pliku manifestu modułu funkcji następujący wpis:
<dist:module ... dist:title="@string/feature_title"> </dist:module>
W menu w sekcji Uwzględnianie podczas instalacji wybierz Nie uwzględniaj moduł w momencie instalacji. Android Studio wstrzykuje do pliku manifestu modułu następujące informacje:
<dist:module ... > <dist:delivery> <dist:on-demand/> </dist:delivery> </dist:module>
Zaznacz pole Fusing, aby ten moduł był dostępny. na urządzeniach z Androidem 4.4 (poziom interfejsu API 20) lub starszym oraz z wieloma plikami APK. Oznacza to, że możesz włączyć działanie tego modułu na żądanie i wyłączyć łączenie, aby pominąć go na urządzeniach, które nie obsługują pobierania i instalowania podzielonych plików APK. Android Studio wstawia zgodnie z Twoim wyborem w pliku manifestu modułu:
<dist:module ...> <dist:fusing dist:include="true | false" /> </dist:module>
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ślny kod, zasoby i organizacja powinny być podobne do tych w standardowym module aplikacji.
Następnie musisz zaimplementować funkcję instalacji na żądanie za pomocą biblioteki Play Feature Delivery.
Dołącz do projektu bibliotekę Play Feature Delivery
Zanim zaczniesz, musisz najpierw dodać do projektu Bibliotekę funkcji Google Play.
Prośba o moduł On Demand
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.
Więcej informacji znajdziesz w pliku manifestu modułu funkcji.
Wyobraź sobie na przykład aplikację, która ma moduł na żądanie do robienia i wysyłania wiadomości z obrazem za pomocą aparatu urządzenia. Moduł ten określa w swoim pliku manifestu wartość split="pictureMessages"
.
ten przykładowy kod wykorzystuje pole SplitInstallManager
do żądania pictureMessages
(wraz z dodatkowym modułem na niektóre filtry promocyjne):
// Creates an instance of SplitInstallManager. val splitInstallManager = SplitInstallManagerFactory.create(context) // Creates a request to install a module. val request = SplitInstallRequest .newBuilder() // You can download multiple on demand modules per // request by invoking the following method for each // module you want to install. .addModule("pictureMessages") .addModule("promotionalFilters") .build() splitInstallManager // Submits the request to install the module through the // asynchronous startInstall() task. Your app needs to be // in the foreground to submit the request. .startInstall(request) // You should also be able to gracefully handle // request state changes and errors. To learn more, go to // the section about how to Monitor the request state. .addOnSuccessListener { sessionId -> ... } .addOnFailureListener { exception -> ... }
// Creates an instance of SplitInstallManager. SplitInstallManager splitInstallManager = SplitInstallManagerFactory.create(context); // Creates a request to install a module. SplitInstallRequest request = SplitInstallRequest .newBuilder() // You can download multiple on demand modules per // request by invoking the following method for each // module you want to install. .addModule("pictureMessages") .addModule("promotionalFilters") .build(); splitInstallManager // Submits the request to install the module through the // asynchronous startInstall() task. Your app needs to be // in the foreground to submit the request. .startInstall(request) // You should also be able to gracefully handle // request state changes and errors. To learn more, go to // the section about how to Monitor the request state. .addOnSuccessListener(sessionId -> { ... }) .addOnFailureListener(exception -> { ... });
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 kontynuować proces użytkownika po instalacji lub odpowiednio obsługiwać błędy, monitoruj stan żądania.
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. Dodatkowo po zainstalowaniu modułu Google Play automatycznie aktualizuje go. Oznacza to, że gdy prześlesz nową wersję pakietu aplikacji, platforma zaktualizuje wszystkie zainstalowane pliki APK należące do Twojej aplikacji. Więcej informacji znajdziesz w artykule 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.
Opóźnianie instalacji modułów na żądanie
Jeśli nie chcesz, aby aplikacja natychmiast pobierała i instalowała moduł na żądanie, możesz odroczyć instalację na czas, 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. W odróżnieniu od SplitInstallManager.startInstall()
aplikacja nie musi być na pierwszym planie, aby zainicjować żądanie opóźnionej instalacji.
// Requests an on demand module to be downloaded when the app enters // the background. You can specify more than one module at a time. splitInstallManager.deferredInstall(listOf("promotionalFilters"))
// Requests an on demand module to be downloaded when the app enters // the background. You can specify more than one module at a time. splitInstallManager.deferredInstall(Arrays.asList("promotionalFilters"));
Prośby o odroczone instalacje są najlepszym rozwiązaniem – nie można śledzić ich
postęp. Dlatego zanim spróbujesz uzyskać dostęp do modułu, który został przez Ciebie oznaczony jako opóźniony, 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, wywołać intencję po instalacji lub prawidłowo obsłużyć błąd żądania, musisz nasłuchiwać aktualizacji stanu z niesynchronizowanego zadania SplitInstallManager.startInstall()
.
Zanim zaczniesz otrzymywać aktualizacje dotyczące prośby o instalację, zarejestruj
detektor i uzyskać identyfikator sesji żądania, jak pokazano poniżej.
// Initializes a variable to later track the session ID for a given request. var mySessionId = 0 // Creates a listener for request status updates. val listener = SplitInstallStateUpdatedListener { state -> if (state.sessionId() == mySessionId) { // Read the status of the request to handle the state update. } } // Registers the listener. splitInstallManager.registerListener(listener) ... splitInstallManager .startInstall(request) // When the platform accepts your request to download // an on demand module, it binds it to the following session ID. // You use this ID to track further status updates for the request. .addOnSuccessListener { sessionId -> mySessionId = sessionId } // You should also add the following listener to handle any errors // processing the request. .addOnFailureListener { exception -> // Handle request errors. } // When your app no longer requires further updates, unregister the listener. splitInstallManager.unregisterListener(listener)
// Initializes a variable to later track the session ID for a given request. int mySessionId = 0; // Creates a listener for request status updates. SplitInstallStateUpdatedListener listener = state -> { if (state.sessionId() == mySessionId) { // Read the status of the request to handle the state update. } }; // Registers the listener. splitInstallManager.registerListener(listener); ... splitInstallManager .startInstall(request) // When the platform accepts your request to download // an on demand module, it binds it to the following session ID. // You use this ID to track further status updates for the request. .addOnSuccessListener(sessionId -> { mySessionId = sessionId; }) // You should also add the following listener to handle any errors // processing the request. .addOnFailureListener(exception -> { // Handle request errors. }); // When your app no longer requires further updates, unregister the listener. splitInstallManager.unregisterListener(listener);
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. Niemożność zainstalowania może być spowodowana problemami takimi jak za mało miejsca na urządzeniu, brak połączenia z internetem lub brak zalogowania się użytkownika w Sklepie Google Play. Sugestie dotyczące postępowania w takich sytuacjach z perspektywy użytkownika zapoznaj się Wytyczne 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:
splitInstallManager .startInstall(request) .addOnFailureListener { exception -> when ((exception as SplitInstallException).errorCode) { SplitInstallErrorCode.NETWORK_ERROR -> { // Display a message that requests the user to establish a // network connection. } SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED -> checkForActiveDownloads() ... } } fun checkForActiveDownloads() { splitInstallManager // Returns a SplitInstallSessionState object for each active session as a List. .sessionStates .addOnCompleteListener { task -> if (task.isSuccessful) { // Check for active sessions. for (state in task.result) { if (state.status() == SplitInstallSessionStatus.DOWNLOADING) { // Cancel the request, or request a deferred installation. } } } } }
splitInstallManager .startInstall(request) .addOnFailureListener(exception -> { switch (((SplitInstallException) exception).getErrorCode()) { case SplitInstallErrorCode.NETWORK_ERROR: // Display a message that requests the user to establish a // network connection. break; case SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED: checkForActiveDownloads(); ... }); void checkForActiveDownloads() { splitInstallManager // Returns a SplitInstallSessionState object for each active session as a List. .getSessionStates() .addOnCompleteListener( task -> { if (task.isSuccessful()) { // Check for active sessions. for (SplitInstallSessionState state : task.getResult()) { if (state.status() == SplitInstallSessionStatus.DOWNLOADING) { // Cancel the request, or request a deferred installation. } } } }); }
W tabeli poniżej opisujemy stany błędów, które mogą wystąpić w aplikacji:
Kod błędu | Opis | Sugerowane działanie |
---|---|---|
ACTIVE_SESSIONS_LIMIT_EXCEEDED | Żądanie zostało odrzucone, ponieważ istnieje co najmniej 1 istniejące żądanie, które jest obecnie pobierane. | Sprawdź, czy są jakieś żądania, które są nadal pobierane, jak pokazano na powyższym przykładzie. |
MODULE_UNAVAILABLE | 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. |
INVALID_REQUEST | Google Play otrzymało żądanie, które jednak jest nieprawidłowy. | Sprawdź, czy informacje zawarte w prośbie są kompletne i poprawne. |
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 | 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 . Więcej informacji znajdziesz w pliku manifestu modułu funkcji.
|
NETWORK_ERROR | Żądanie nie zostało zrealizowane z powodu błędu sieci. | Poprowad użytkownika o ustanowienie połączenia z siecią lub o przełączenie się na inną 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. |
INCOMPATIBLE_WITH_EXISTING_SESSION | Prośba zawiera co najmniej 1 moduł, który został już zażądany, ale nie został jeszcze zainstalowany. | Utwórz nowe żądanie, które nie zawiera modułów, których aplikacja już zażądała, lub poczekaj, aż wszystkie obecnie żądane moduły zostaną zainstalowane, zanim spróbujesz ponownie wysłać żądanie.
Pamiętaj, że żądanie modułu, który jest już zainstalowany, nie powoduje rozwiązania błędu. |
WYKONANY_USŁUGA | Usługa odpowiedzialna za obsługę tego żądania nie działa. | Ponownie prześlij prośbę.
Usługa |
ZA MAŁO_MIEJSCA | Na urządzeniu jest za mało wolnego miejsca na zainstalowanie modułu funkcji. | Powiadom użytkownika, że nie ma wystarczającej ilości miejsca na dane do zainstalowania funkcji. |
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR | SplitCompat nie może wczytać modułu funkcji. | Te błędy powinny zniknąć automatycznie po ponownym uruchomieniu aplikacji. |
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. |
APP_NOT_OWNED | 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. |
BŁĄD_WEWNĘTRZNY | W Sklepie Play wystąpił błąd wewnętrzny. | Ponownie prześlij prośbę. |
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
Po zarejestrowaniu listenera i zarejestrowaniu identyfikatora sesji dla żądania użyj funkcji StateUpdatedListener.onStateUpdate()
do obsługi zmian stanu, jak pokazano poniżej.
override fun onStateUpdate(state : SplitInstallSessionState) { if (state.status() == SplitInstallSessionStatus.FAILED && state.errorCode() == SplitInstallErrorCode.SERVICE_DIED) { // Retry the request. return } if (state.sessionId() == mySessionId) { when (state.status()) { SplitInstallSessionStatus.DOWNLOADING -> { val totalBytes = state.totalBytesToDownload() val progress = state.bytesDownloaded() // Update progress bar. } SplitInstallSessionStatus.INSTALLED -> { // After a module is installed, you can start accessing its content or // fire an intent to start an activity in the installed module. // For other use cases, see access code and resources from installed modules. // If the request is an on demand module for an Android Instant App // running on Android 8.0 (API level 26) or higher, you need to // update the app context using the SplitInstallHelper API. } } } }
@Override public void onStateUpdate(SplitInstallSessionState state) { if (state.status() == SplitInstallSessionStatus.FAILED && state.errorCode() == SplitInstallErrorCode.SERVICE_DIES) { // Retry the request. return; } if (state.sessionId() == mySessionId) { switch (state.status()) { case SplitInstallSessionStatus.DOWNLOADING: int totalBytes = state.totalBytesToDownload(); int progress = state.bytesDownloaded(); // Update progress bar. break; case SplitInstallSessionStatus.INSTALLED: // After a module is installed, you can start accessing its content or // fire an intent to start an activity in the installed module. // For other use cases, see access code and resources from installed modules. // If the request is an on demand module for an Android Instant App // running on Android 8.0 (API level 26) or higher, you need to // update the app context using the SplitInstallHelper API. } } }
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 i wkrótce rozpocznie się pobieranie. | zainicjuj komponenty interfejsu, np. pasek postępu, aby przekazać użytkownikom opinię o pobieranym pliku. |
REQUIRES_USER_CONFIRMATION | Pobieranie wymaga potwierdzenia przez użytkownika. Najczęściej ten stan występuje, gdy aplikacja nie została zainstalowana za pomocą Google Play. | Poproś użytkownika o potwierdzenie pobrania funkcji z Google Play. Więcej informacji znajdziesz w sekcji uzyskaj potwierdzenie użytkownika. |
POBIERANIE | Trwa pobieranie. | Jeśli udostępniasz pasek postępu pobierania, użyj metod SplitInstallSessionState.bytesDownloaded() i SplitInstallSessionState.totalBytesToDownload() , aby zaktualizować interfejs użytkownika (patrz przykład kodu nad tą tabelą). |
POBRANE | Moduł został pobrany na urządzenie, ale instalacja jeszcze się nie rozpoczęła. | Aplikacje powinny włączać SplitCompat, aby mieć dostęp do pobranych modułów i nie wyświetlać tego stanu. Jest to konieczne, aby uzyskać dostęp do kodu i zasobów modułu funkcji. |
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 zasoby w module, aby kontynuować ścieżkę użytkownika.
Jeśli moduł dotyczy aplikacji błyskawicznej na Androida uruchomionej na Androidzie 8.0 (poziom interfejsu API 26)
lub wyższej, musisz użyć |
BŁĄD | Żądanie nie powiodło się, zanim moduł został zainstalowany na urządzeniu. | Poproś użytkownika o ponowne przesłanie prośby lub jej anulowanie. |
ANULuję | Urządzenie anuluje żądanie. | 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 prośby o pobieranie. 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 takie prompty:
override fun onSessionStateUpdate(state: SplitInstallSessionState) { if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) { // Displays a confirmation for the user to confirm the request. splitInstallManager.startConfirmationDialogForResult( state, // an activity result launcher registered via registerForActivityResult activityResultLauncher) } ... }
@Override void onSessionStateUpdate(SplitInstallSessionState state) { if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) { // Displays a confirmation for the user to confirm the request. splitInstallManager.startConfirmationDialogForResult( state, // an activity result launcher registered via registerForActivityResult activityResultLauncher); } ... }
Możesz zarejestrować program uruchamiający wyniki aktywności, używając wbudowanego
ActivityResultContracts.StartIntentSenderForResult
umowy. Zobacz interfejsy API wyników aktywności.
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 wybierze opcji przed zniszczeniem okna dialogowego, stan żądania pozostanie taki sam jak
REQUIRES_USER_CONFIRMATION
. Aplikacja może ponownie poprosić użytkownika o wykonanie żądania.
Aby otrzymać wywołanie zwrotne z odpowiedzią użytkownika, możesz zastąpić parametr ActivityResultCallback, tak jak poniżej.
registerForActivityResult(StartIntentSenderForResult()) { result: ActivityResult -> { // Handle the user's decision. For example, if the user selects "Cancel", // you may want to disable certain functionality that depends on the module. } }
registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { // Handle the user's decision. For example, if the user selects "Cancel", // you may want to disable certain functionality that depends on the module. } });
Anulowanie prośby o instalację
Jeśli aplikacja musi anulować żądanie przed jego zainstalowaniem, może wywołać metodę cancelInstall()
, korzystając z identyfikatora sesji żądania, jak pokazano poniżej.
splitInstallManager // Cancels the request for the given session ID. .cancelInstall(mySessionId)
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, aplikacja musi włączyć bibliotekę SplitCompat zarówno dla aplikacji, jak i każdej aktywności w modułach funkcji, które aplikacja pobiera.
Pamiętaj jednak, że po pobraniu modułu platforma ma dostęp do jego treści przez pewien czas (w niektórych przypadkach przez kilka dni):
- 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 pobranej biblioteki, musisz włączyć SplitCompat, korzystając z jednej z metod opisanych w poniższych sekcjach.
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 obsługi SplitCompat jest zadeklarowanie SplitCompatApplication
jako podklasy Application
w pliku 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: automatycznie pobrane moduły funkcji.
Wywołuj SplitCompat w czasie działania
Możesz też włączyć SplitCompat w określonych działaniach lub usługach w czasie wykonywania.
Włączenie tej opcji w ten sposób jest wymagane do uruchamiania działań zawartych w modułach 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:
class MyApplication : SplitCompatApplication() { ... }
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:
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) // Emulates installation of future on demand modules using SplitCompat. SplitCompat.install(this) }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // Emulates installation of future on demand modules using SplitCompat. SplitCompat.install(this); }
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:
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) if (!InstantApps.isInstantApp(this)) { SplitCompat.install(this) } }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); if (!InstantApps.isInstantApp(this)) { SplitCompat.install(this); } }
Włącz SplitCompat do działań w module
Po włączeniu obsługi SplitCompat w aplikacji podstawowej musisz włączyć obsługę SplitCompat dla każdej aktywności, którą aplikacja pobiera w module funkcji. Aby to zrobić:
użyj metody SplitCompat.installActivity()
w ten sposób:
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) // Emulates installation of on demand modules using SplitCompat. SplitCompat.installActivity(this) }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // Emulates installation of on demand modules using SplitCompat. SplitCompat.installActivity(this); }
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.
startActivity(Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...))
startActivity(new Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...));
Pierwszy parametr funkcji setClassName
to nazwa pakietu aplikacji, a drugi to pełna nazwa klasy działania.
W ćwiczeniu w module funkcji pobranym na żądanie musisz włącz w niej narzędzie SplitCompat.
Uruchamianie usługi zdefiniowanej w module funkcji
Usługi zdefiniowane w modułach funkcji możesz uruchamiać za pomocą
startService()
po włączeniu narzędzia SplitCompat.
startService(Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...))
startService(new Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...));
Eksportowanie komponentu zdefiniowanego w module funkcji
Nie należy umieszczać w modułach opcjonalnych komponentów wyeksportowanych z Androida.
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, a 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 moduł jest obecny, komponent zastępczy może uruchomić komponent wewnętrzny z modułu za pomocą Intent
, przekazując intencję z aplikacji wywołującej. Jeśli moduł jest nieobecny, komponent może pobrać moduł lub zwrócić odpowiedni komunikat o błędzie do aplikacji wywołującej.
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
Dostęp do kodu podstawowego z modułu
Kod znajdujący się w module podstawowym 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ęć.
Dostęp do kodu modułu z innego modułu
Obiekt lub klasa w module nie mogą być dostępne statycznie z innego modułu, ale można uzyskać do nich dostęp pośrednio, korzystając z odzwierciedlenia.
Pamiętaj, że ze względu na koszty związane z odbiciem światła należy zwracać uwagę na to, jak często to się zdarza. 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:
// In the base module interface MyInterface { fun hello(): String } // In the feature module object MyInterfaceImpl : MyInterface { override fun hello() = "Hello" } // In the base module, where we want to access the feature module code val stringFromModule = (Class.forName("com.package.module.MyInterfaceImpl") .kotlin.objectInstance as MyInterface).hello();
// In the base module public interface MyInterface { String hello(); } // In the feature module public class MyInterfaceImpl implements MyInterface { @Override public String hello() { return "Hello"; } } // In the base module, where we want to access the feature module code String stringFromModule = ((MyInterface) Class.forName("com.package.module.MyInterfaceImpl").getConstructor().newInstance()).hello();
Dostęp do zasobów i komponentów z innego modułu
Po zainstalowaniu modułu możesz uzyskać dostęp do zasobów i komponentów w module w standardowy sposób, z dwoma wyjątkami:
- 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 w nowo zainstalowanym module z innego zainstalowanego modułu aplikacji, musisz to zrobić za pomocą kontekstu aplikacji. Kontekst komponentu, który próbuje uzyskać dostęp do zasobów, nie zostanie jeszcze zaktualizowany. Możesz też ponownie utworzyć ten komponent (np. wywołując metodę Activity.recreate()) lub ponownie zainstalować SplitCompat po zainstalowaniu modułu funkcji.
Wczytywanie kodu natywnego w aplikacji przy użyciu dostarczania na żądanie
Zalecamy używanie ReLinkera do ładowania wszystkich natywnych bibliotek podczas dostarczania modułów funkcji na żądanie. ReLinker rozwiązuje problem z wczytywaniem bibliotek natywnych po zainstalowaniu 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 załadowanie jego kodu natywnego za pomocą ReLinkera. 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 w kodzie natywnym używasz funkcji dlopen()
do wczytywania biblioteki zdefiniowanej w opcjonalnym module, nie będzie ona działać z względnymi ścieżkami biblioteki.
Najlepszym rozwiązaniem jest pobranie z kodu Java ścieżki bezwzględnej biblioteki za pomocą funkcji ClassLoader.findLibrary()
, a potem użycie jej w wywołaniu 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 Kontekst utworzony przez aplikację przed zainstalowaniem modułu (np. zapisany w zmiennej) nie zawiera treści nowego modułu. Nowy kontekst jest jednak potrzebny. Można go uzyskać, na przykład za pomocą createPackageContext
.
// Generate a new context as soon as a request for a new module // reports as INSTALLED. override fun onStateUpdate(state: SplitInstallSessionState ) { if (state.sessionId() == mySessionId) { when (state.status()) { ... SplitInstallSessionStatus.INSTALLED -> { val newContext = context.createPackageContext(context.packageName, 0) // If you use AssetManager to access your app’s raw asset files, you’ll need // to generate a new AssetManager instance from the updated context. val am = newContext.assets } } } }
// Generate a new context as soon as a request for a new module // reports as INSTALLED. @Override public void onStateUpdate(SplitInstallSessionState state) { if (state.sessionId() == mySessionId) { switch (state.status()) { ... case SplitInstallSessionStatus.INSTALLED: Context newContext = context.createPackageContext(context.getPackageName(), 0); // If you use AssetManager to access your app’s raw asset files, you’ll need // to generate a new AssetManager instance from the updated context. AssetManager am = newContext.getAssets(); } } }
Aplikacje błyskawiczne na Androida na Androida 8.0 lub nowszego
Gdy żądasz przesłania modułu na żądanie do aplikacji błyskawicznej na Androida w wersji 8.0 (poziom interfejsu API 26) lub nowszej, po zgłoszeniu prośby o instalację (INSTALLED
) musisz zaktualizować aplikację, dodając kontekst nowego modułu za pomocą wywołania SplitInstallHelper.updateAppInfo(Context context)
.
W przeciwnym razie aplikacja nie zna jeszcze kodu modułu.
i zasobami. Po zaktualizowaniu metadanych aplikacji załaduj zawartość modułu podczas następnego zdarzenia głównego wątku, wywołując nowe Handler
, jak pokazano poniżej:
override fun onStateUpdate(state: SplitInstallSessionState ) { if (state.sessionId() == mySessionId) { when (state.status()) { ... SplitInstallSessionStatus.INSTALLED -> { // You need to perform the following only for Android Instant Apps // running on Android 8.0 (API level 26) and higher. if (BuildCompat.isAtLeastO()) { // Updates the app’s context with the code and resources of the // installed module. SplitInstallHelper.updateAppInfo(context) Handler().post { // Loads contents from the module using AssetManager val am = context.assets ... } } } } } }
@Override public void onStateUpdate(SplitInstallSessionState state) { if (state.sessionId() == mySessionId) { switch (state.status()) { ... case SplitInstallSessionStatus.INSTALLED: // You need to perform the following only for Android Instant Apps // running on Android 8.0 (API level 26) and higher. if (BuildCompat.isAtLeastO()) { // Updates the app’s context with the code and resources of the // installed module. SplitInstallHelper.updateAppInfo(context); new Handler().post(new Runnable() { @Override public void run() { // Loads contents from the module using AssetManager AssetManager am = context.getAssets(); ... } }); } } } }
Wczytaj biblioteki C/C++
Jeśli chcesz wczytać biblioteki C/C++ z modułu, który został już pobrany na urządzenie w ramach aplikacji błyskawicznej, użyj SplitInstallHelper.loadLibrary(Context context, String libName)
, jak pokazano poniżej:
override fun onStateUpdate(state: SplitInstallSessionState) { if (state.sessionId() == mySessionId) { when (state.status()) { SplitInstallSessionStatus.INSTALLED -> { // Updates the app’s context as soon as a module is installed. val newContext = context.createPackageContext(context.packageName, 0) // To load C/C++ libraries from an installed module, use the following API // instead of System.load(). SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”) ... } } } }
public void onStateUpdate(SplitInstallSessionState state) { if (state.sessionId() == mySessionId) { switch (state.status()) { case SplitInstallSessionStatus.INSTALLED: // Updates the app’s context as soon as a module is installed. Context newContext = context.createPackageContext(context.getPackageName(), 0); // To load C/C++ libraries from an installed module, use the following API // instead of System.load(). SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”); ... } } }
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.
val installedModules: Set<String> = splitInstallManager.installedModules
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.
// Specifies two feature modules for deferred uninstall. splitInstallManager.deferredUninstall(listOf("pictureMessages", "promotionalFilters"))
// Specifies two feature modules for deferred uninstall. splitInstallManager.deferredUninstall(Arrays.asList("pictureMessages", "promotionalFilters"));
Odinstalowanie modułu nie następuje natychmiast. To znaczy,
w razie potrzeby odinstalowuje je w tle, aby zaoszczędzić miejsce.
Aby sprawdzić, czy urządzenie usunęło moduł, wywołaj polecenie SplitInstallManager.getInstalledModules()
i sprawdź wynik w sposób opisany w poprzedniej sekcji.
Pobieranie dodatkowych zasobów językowych
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 Twoja aplikacja miała dostęp do dodatkowych zasobów językowych (np. do implementowania selektora języka), możesz pobrać je na żądanie z biblioteki funkcji Google Play. Proces jest podobny do pobierania modułu funkcji, jak pokazano poniżej.
// Captures the user’s preferred language and persists it // through the app’s SharedPreferences. sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply() ... // Creates a request to download and install additional language resources. val request = SplitInstallRequest.newBuilder() // Uses the addLanguage() method to include French language resources in the request. // Note that country codes are ignored. That is, if your app // includes resources for “fr-FR” and “fr-CA”, resources for both // country codes are downloaded when requesting resources for "fr". .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))) .build() // Submits the request to install the additional language resources. splitInstallManager.startInstall(request)
// Captures the user’s preferred language and persists it // through the app’s SharedPreferences. sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply(); ... // Creates a request to download and install additional language resources. SplitInstallRequest request = SplitInstallRequest.newBuilder() // Uses the addLanguage() method to include French language resources in the request. // Note that country codes are ignored. That is, if your app // includes resources for “fr-FR” and “fr-CA”, resources for both // country codes are downloaded when requesting resources for "fr". .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))) .build(); // Submits the request to install the additional language resources. splitInstallManager.startInstall(request);
Prośba jest obsługiwana tak, jakby była prośbą o moduł funkcji. To znaczy, możesz monitorować stan żądania w zwykły sposób.
Jeśli aplikacja nie wymaga natychmiastowego zainstalowania dodatkowych zasobów językowych, możesz odłożyć instalację na czas, gdy aplikacja działa w tle (patrz poniżej).
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
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 wywołać metodę SplitCompat.installActivity()
w ramach metody attachBaseContext()
każdej aktywności, która wymaga dostępu do tych zasobów, jak pokazano poniżej.
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) SplitCompat.installActivity(this) }
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); SplitCompat.installActivity(this); }
W przypadku każdej aktywności, w której chcesz używać zasobów językowych pobranych przez aplikację, zaktualizuj kontekst podstawowy i ustaw nowy język za pomocą funkcji Configuration
:
override fun attachBaseContext(base: Context) { val configuration = Configuration() configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))) val context = base.createConfigurationContext(configuration) super.attachBaseContext(context) SplitCompat.install(this) }
@Override protected void attachBaseContext(Context base) { Configuration configuration = new Configuration(); configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION))); Context context = base.createConfigurationContext(configuration); super.attachBaseContext(context); SplitCompat.install(this); }
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()
.
when (state.status()) { SplitInstallSessionStatus.INSTALLED -> { // Recreates the activity to load resources for the new language // preference. activity.recreate() } ... }
switch (state.status()) { case SplitInstallSessionStatus.INSTALLED: // Recreates the activity to load resources for the new language // preference. activity.recreate(); ... }
Odinstalowywanie dodatkowych zasobów językowych
Podobnie jak w przypadku modułów funkcji, dodatkowe zasoby możesz odinstalować w dowolnym momencie. Zanim poprosisz o odinstalowanie, możesz najpierw sprawdzić, które języki są obecnie zainstalowane.
val installedLanguages: Set<String> = splitInstallManager.installedLanguages
Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();
Następnie możesz zdecydować, które języki chcesz odinstalować, korzystając z metody deferredLanguageUninstall()
, jak pokazano poniżej.
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
Testowanie lokalnie instalacji modułu
Biblioteka Play Feature Delivery pozwala lokalnie przetestować, czy aplikacja tych treści bez łączenia się ze Sklepem Play:
- Wysyłanie żądań i monitorowanie instalacji modułów.
- Obsługa błędów instalacji.
- Użyj formatu
SplitCompat
aby uzyskać dostęp do modułów.
Na tej stronie opisaliśmy, jak wdrożyć podzielone pliki APK aplikacji na urządzenie testowe, aby Play Feature Delivery automatycznie używało tych plików do symulowania żądania, pobierania i instalowania modułów ze Sklepu Play.
Chociaż nie musisz wprowadzać żadnych zmian w logice aplikacji, musisz spełnić te wymagania:
- Pobierz i zainstaluj najnowszą wersję aplikacji
bundletool
. Musisz użyć narzędziabundletool
, aby utworzyć nowy zestaw pakietów APK do zainstalowania z pakietu aplikacji.
Tworzenie zestawu plików APK
Jeśli jeszcze go nie masz, utwórz dzielone pakiety APK swojej aplikacji w ten sposób:
- Utwórz pakiet aplikacji dla swojej aplikacji, korzystając z jednej z tych metod:
- Użyj Android Studio i wtyczki Androida do aplikacji Gradle do skompilowania i podpisania aplikacji pakietu Android App Bundle.
- Utwórz pakiet aplikacji z poziomu wiersza poleceń.
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 --outputmy_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. Możesz wykonać obie te czynności za pomocą tego polecenia:
bundletool install-apks --apksmy_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
alternatywa dla funkcji SplitInstallManager
, nazwana
FakeSplitInstallManager
aby zażądać jego modułu. Gdy użyjesz bundletool
z flagą --local-testing
, aby utworzyć zestaw plików APK i wdrożyć je na urządzeniu testowym, zawiera ona metadane, które instruują Bibliotekę funkcji Play do automatycznego przełączania wywołań interfejsu API aplikacji na wywołanie FakeSplitInstallManager
zamiast 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. Aby uzyskać dostęp do FakeSplitInstallManager
w testach, możesz uzyskać jego instancję za pomocą funkcji FakeSplitInstallManagerFactory
, jak pokazano poniżej:
// Creates an instance of FakeSplitInstallManager with the app's context. val fakeSplitInstallManager = FakeSplitInstallManagerFactory.create(context) // Tells Play Feature Delivery Library to force the next module request to // result in a network error. fakeSplitInstallManager.setShouldNetworkError(true)
// Creates an instance of FakeSplitInstallManager with the app's context. FakeSplitInstallManager fakeSplitInstallManager = FakeSplitInstallManagerFactory.create(context); // Tells Play Feature Delivery Library to force the next module request to // result in a network error. fakeSplitInstallManager.setShouldNetworkError(true);