Biblioteka Jetpack WindowManager umożliwia deweloperom aplikacji obsługę nowych formatów urządzeń i środowisk wielookiennych.
Rozszerzenia WindowManager (Extensions) to moduł platformy Androida, który wymaga akceptacji użytkownika i umożliwia korzystanie z różnych funkcji Jetpack WindowManager. Moduł jest zaimplementowany w AOSP w regionie frameworks/base/libs/WindowManager/Jetpack
i udostępniany na urządzeniach obsługujących funkcje WindowManager.
Rozkład modułów rozszerzeń
Rozszerzenia są kompilowane w bibliotekę .jar
i umieszczane w partycji system_ext
na urządzeniu, jeśli w pliku Makefile urządzenia są włączone rozszerzenia.
Aby włączyć rozszerzenia na urządzeniu, do pliku DDEX urządzenia dodaj ten fragment:
$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)
Umożliwia to włączenie pakietów androidx.window.extensions
i androidx.window.sidecar
na urządzeniu oraz ustawienie właściwości persist.wm.extensions.enabled
.
Umieszczenie tych pakietów w pliku Makefile spowoduje też umieszczenie deklaracji w etc/permissions/
, dzięki czemu będą one dostępne dla procesów aplikacji. Zwykle moduły są ładowane i wykonywane w ramach procesu aplikacji w czasie wykonywania, gdy są używane przez bibliotekę Jetpack WindowManager, co sprawia, że ich działanie jest podobne do działania kodu frameworku po stronie klienta, jak pokazano na poniższym rysunku:
Moduł androidx.window.extensions
to obecny moduł rozszerzeń, który jest obecnie rozwijany. Moduł androidx.window.sidecar
to starszy moduł dostępny w celu zapewnienia zgodności z najwcześniejszymi wersjami Jetpack WindowManager, ale aplikacja pomocnicza nie jest już aktywnie obsługiwana.
Na rysunku poniżej pokazano logikę określania użycia funkcji androidx.window.extensions
lub androidx.window.sidecar
.
Moduły rozszerzeń
Rozszerzenia zapewniają funkcje okna na składanych urządzeniach z dużym ekranem oraz na urządzeniach obsługujących okna na zewnętrznych wyświetlaczach. Dostępne obszary:
Rozszerzenia implementowane przez OEM-ów mogą zawierać komponenty null lub komponenty z domyślnymi implementacjami metod lub implementacjami zastępczymi w interfejsie WindowExtensions
, jeśli sprzęt urządzenia nie obsługuje odpowiednich funkcji, chyba że funkcja została wyraźnie zażądana w dokumentacji definicji zgodności (CDD) 7.1.1.1.
Interfejsy API rozszerzeń i Jetpacka
Moduł rozszerzeń WindowManager udostępnia własny interfejs API oprócz publicznych interfejsów API platformy. Moduł rozszerzeń jest publicznie rozwijany w bibliotece Jetpacka androidx.window.extensions
, która nie jest przeznaczona dla programistów, aby Jetpack WindowManager (androidx.window
) mógł się do niej odwoływać w czasie kompilacji. Interfejs Extensions API zwykle udostępnia interfejsy API niskiego poziomu.
Interfejsy API udostępniane przez rozszerzenia są przeznaczone tylko do użytku biblioteki Jetpack WindowManager. Interfejsy API rozszerzeń nie są przeznaczone do bezpośredniego wywoływania przez deweloperów aplikacji. Nie należy dodawać biblioteki rozszerzeń jako zależności aplikacji w pliku kompilacji Gradle, aby zapewnić prawidłowe działanie. Unikaj wstępnego kompilowania biblioteki rozszerzeń bezpośrednio do aplikacji. Zamiast tego polegaj na wczytywaniu środowiska wykonawczego, aby uniknąć wczytywania kombinacji klas rozszerzeń, które są wstępnie skompilowane oraz udostępnione w czasie działania.
Jetpack WindowManager (androidx.window
) należy dodać jako zależność aplikacji i udostępniać publiczne interfejsy API dla programistów, w tym dla funkcji rozszerzeń WindowManager. Biblioteka WindowManager automatycznie wczytuje rozszerzenia do procesu aplikacji i opatruje interfejsy API rozszerzeń niższego poziomu w abstrakcje wyższego poziomu i bardziej precyzyjne interfejsy. Interfejsy WindowManager Jetpack API są zgodne ze standardami tworzenia nowoczesnych aplikacji na Androida i mają zapewnić wygodną interoperacyjność dzięki integracji z bazami kodu korzystającymi z innych bibliotek AndroidaX.
Wersje i aktualizacje rozszerzeń
Moduł rozszerzeń może być aktualizowany wraz z rocznymi lub kwartalnymi aktualizacjami platformy Android. Kwartalne aktualizacje umożliwiają zwiększanie poziomu interfejsu Extensions API między aktualizacjami API platformy Androida, co umożliwia szybszą iterację oraz umożliwia producentom OEM możliwość dodawania oficjalnych interfejsów API do nowych funkcji tuż przed premierą sprzętu.
W tabeli poniżej znajdziesz wersje interfejsu androidx.window.extensions
API dla różnych wersji Androida.
Wersja platformy Android | Poziom interfejsu API WindowManager Extensions | Wersja interfejsu API androidx.window.extensions |
---|---|---|
Android 15 | 6 | 1.5.0 (wkrótce) |
Android 14 QPR3 | 5 | 1.4.0 (wkrótce) |
Android 14 QPR1 | 4 | 1.3.0 |
Android 14 | 3 | 1.2.0 |
Android 13 QPR3 | 2 | 1.1.0 |
Android 13 | 1 | 1.0.0 |
Android 12L | 1 | 1.0.0 |
Poziom interfejsu API rozszerzeń (kolumna środkowa) zwiększa się za każdym razem, gdy pojawia się nowa stabilna powierzchnia interfejsu API (prawa kolumna).
Zgodność wstecz i do przodu
Jetpack WindowManager radzi sobie z zaawansowanymi aktualizacjami interfejsu API, szybkim rozwojem interfejsu API i wsteczną zgodnością. Gdy kod biblioteki jest wykonywany w procesie aplikacji, sprawdza deklarowany poziom interfejsu API rozszerzeń i daje dostęp do funkcji zgodnie z deklarowanym poziomem.
Aby chronić aplikację przed awariami w czasie działania, WindowManager wykonuje też weryfikację interfejsów API rozszerzeń w czasie działania za pomocą mechanizmu Java Reflection zgodnie z deklarowanym poziomem interfejsu API rozszerzeń. W razie wystąpienia niezgodności WindowManager może wyłączyć możliwość korzystania z rozszerzeń (częściowo lub całkowicie) i zgłosić odpowiednie funkcje jako niedostępne dla aplikacji.
Rozszerzenia WindowManager są zaimplementowane jako moduł system_ext
, który wykorzystuje interfejsy API platformy prywatnej do wywoływania podstawowych usług systemu WindowManager, DeviceStateManager
i innych usług systemowych w ramach implementacji funkcji rozszerzeń.
Nie można zachować zgodności z przedpremierowymi wersjami rozszerzeń przed odpowiednimi kwartalnymi lub rocznymi wydaniami na platformie Androida, na których wersje są finalizowane. Pełną historię interfejsów API rozszerzeń można znaleźć w sekcji Pliki tekstowe interfejsu API window:extensions:extensions
.
Aby zachować zgodność wstecz, nowsze wersje rozszerzeń muszą nadal działać ze starszymi wersjami WindowManagera skompilowanych w aplikacje. Aby to zagwarantować, w każdej nowej wersji interfejsu Extensions API są dodawane tylko nowe interfejsy API – starsze nie są usuwane. Oznacza to, że aplikacje ze starszymi wersjami WindowManager mogą nadal korzystać ze starszych interfejsów API rozszerzeń, które zostały skompilowane na podstawie ich utworzenia.
Weryfikacja CTS zapewnia, że w przypadku każdej zadeklarowanej wersji interfejsów API rozszerzeń na urządzeniu wszystkie interfejsy API dla tej i poprzednich wersji są dostępne i działają.
Wydajność
Moduł rozszerzeń jest domyślnie zapisany w pamięci podręcznej w programach wczytujących klas systemu innych niż bootclasspath, począwszy od Androida 14 (poziom interfejsu API 34), dlatego nie ma wpływu na wydajność, ponieważ wczytuje się on do pamięci podczas uruchamiania aplikacji. Korzystanie z funkcji poszczególnych modułów może mieć niewielki wpływ na charakterystykę wydajności aplikacji, gdy między klientem a serwerem są wykonywane dodatkowe wywołania IPC.
Moduły
Umieszczanie aktywności
Komponent osadzania aktywności udostępnia zestaw funkcji, które umożliwiają aplikacjom organizowanie prezentacji okna aktywności w ramach aplikacji nadrzędnej. Obejmuje to wyświetlanie 2 czynności obok siebie w układzie z wieloma panelami, co ułatwia optymalizację dużych ekranów w przypadku starszych aplikacji.
Komponent umożliwiający umieszczanie aktywności musi być dostępny na wszystkich urządzeniach z wbudowanym wyświetlaczem o rozmiarze równym lub większym niż sw600 dp
.
Umieszczenie w ramce musi być też włączone na urządzeniach, które obsługują połączenia z wyświetlaczami zewnętrznymi, ponieważ aplikacja może być wyświetlana w większym rozmiarze, gdy wyświetlacze zewnętrzne są podłączone w czasie działania.
Konfiguracja urządzenia
Nie jest wymagana żadna konkretna konfiguracja urządzenia poza włączeniem modułu rozszerzeń zgodnie z opisem w sekcji Rozkład modułów rozszerzeń. Warto włączyć rozszerzenia na wszystkich urządzeniach, które obsługują tryb wielookienkowy. W przyszłych wersjach Androida rozszerzenia będą prawdopodobnie wymagane w przypadku typowych konfiguracji urządzeń przenośnych i z dużym ekranem.
Informacje o układzie okna
Komponent informacji o układzie okna określa położenie i stan zawiasu na urządzeniu składanym, gdy zawias przecina okno aplikacji. Informacje o układzie okna umożliwiają aplikacjom reagowanie na optymalne układy i wyświetlanie ich w trybie stołu na urządzeniach składanych. Szczegółowe informacje o wykorzystaniu znajdziesz w artykule Informacje o umieszczeniu aplikacji na ekranie.
Składane urządzenia z Androidem, które mają zawias łączący oddzielne lub ciągłe obszary panelu wyświetlacza, muszą udostępniać informacje o tym zawiasie aplikacjom za pomocą WindowLayoutComponent
.
Położenie zawiasu i granice zawiasu muszą być zgłaszane w odniesieniu do okna aplikacji wskazywanego przez parametr Context
przekazywany do interfejsu API. Jeśli granice okna aplikacji nie pokrywają się z granicami zawiasów, zawiasy DisplayFeature
nie muszą być zgłaszane. Nie musisz też raportować funkcji wyświetlania, jeśli ich pozycja nie może być wiarygodnie raportowana, na przykład gdy użytkownik może swobodnie przenosić okno aplikacji w trybie wielookiennym lub trybie Letterbox.
W przypadku funkcji składania stany muszą być aktualizowane, gdy pozycja zawiasu zmienia się między stabilnymi stanami. Domyślnie w stanie wyświetlania w płaskim formacie interfejs API musi zwracać wartość FoldingFeature.State.FLAT
.
Jeśli sprzęt urządzenia może znajdować się w trybie złożonym do połowy w stabilnym stanie, interfejs API musi zgłosić FoldingFeature.State.HALF_OPENED
.
W interfejsie API nie ma stanu zamkniętego, ponieważ w takim przypadku okno aplikacji albo nie byłoby widoczne, albo nie przekraczałoby granic zawiasów.
Konfiguracja urządzenia
Aby umożliwić implementację funkcji składania, producenci OEM muszą:
Skonfiguruj stany urządzeń w usłudze
device_state_configuration.xml
, których ma używaćDeviceStateManagerService
. Więcej informacji znajdziesz wDeviceStateProviderImpl.java
.Jeśli domyślne implementacje funkcji
DeviceStateProvider
lubDeviceStatePolicy
nie są odpowiednie na danym urządzeniu, możesz użyć implementacji niestandardowej.Włącz moduł Rozszerzenia w sposób opisany w sekcji Dystrybucja modułu Rozszerzenia.
Określ lokalizację funkcji wyświetlania w zasobach napisów
com.android.internal.R.string.config_display_features
(zwykle wframeworks/base/core/res/res/values/config.xml
w nakładce na urządzeniu).Oczekiwany format ciągu znaków:
<type>-[<left>,<top>,<right>,<bottom>]
Wartość
type
może być równafold
lubhinge
. Wartościleft
,top
,right
ibottom
to całkowite współrzędne pikseli w przestrzeni współrzędnych wyświetlacza w naturalnym ułożeniu wyświetlacza. Ciąg konfiguracji może zawierać wiele funkcji wyświetlania rozdzielonych średnikami.Na przykład:
<!-- Jetpack WindowManager display features --> <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
Określ mapowanie między wewnętrznymi identyfikatorami stanu urządzenia używanymi w
DeviceStateManager
a konstantami stanu publicznego wysyłanymi do deweloperów wcom.android.internal.R.array.config_device_state_postures
.Oczekiwany format każdego wpisu:
<device_specific_state_identifier>:<Jetpack WindowManager state identifier>
Obsługiwane identyfikatory stanów:
COMMON_STATE_NO_FOLDING_FEATURES = 1
: stan nie ma funkcji składania, które można by zgłosić. Może to być na przykład zamknięty stan typowego urządzenia z ekranem głównym po wewnętrznej stronie.COMMON_STATE_HALF_OPENED = 2
: funkcja zwijania jest otwarta w połowie.COMMON_STATE_FLAT = 3
: funkcja składania jest płaska. Może to być na przykład stan otwarty w typowym składanym urządzeniu, którego ekran główny jest od strony wewnętrznej.COMMON_STATE_USE_BASE_STATE = 1000
: w Androidzie 14 wartość, której można używać w emulowanych stanach, w których stan zawiasu jest określany na podstawie stanu podstawowego, jak określono wCommonFoldingFeature.java
.
Więcej informacji:
DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int)
.Na przykład:
<!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.--> <string-array name="config_device_state_postures" translatable="false"> <item>0:1</item> <!-- CLOSED : COMMON_STATE_NO_FOLDING_FEATURES --> <item>1:2</item> <!-- HALF_OPENED : COMMON_STATE_HALF_OPENED --> <item>2:3</item> <!-- OPENED : COMMON_STATE_FLAT --> <item>3:1</item> <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES --> <item>4:1000</item> <!-- CONCURRENT : COMMON_STATE_USE_BASE_STATE --> </string-array>
Obszar okna
Komponent obszaru okna udostępnia zestaw funkcji, które umożliwiają aplikacjom dostęp do dodatkowych wyświetlaczy i obszarów wyświetlacza na niektórych składanych urządzeniach oraz urządzeniach z wielorakiem wyświetlaczem.
Tryb wyświetlacza tylnego umożliwia aplikacji wyświetlanie interfejsu podglądu aparatu na wyświetlaczu zewnętrznym składanego urządzenia, aby umożliwić korzystanie z głównego aparatu urządzenia do robienia selfie i filmów. Urządzenia z urządzeniami zgodnymi z Androidem (zgodnie z definicjami atrybutów takich jak rozmiar, gęstość i dostępne funkcje nawigacji) muszą zapewniać dostęp do trybu tylnego wyświetlacza.
W Androidzie 14 tryb podwójnego ekranu umożliwia aplikacjom, które działają na wewnętrznym wyświetlaczu urządzenia składanego, wyświetlanie dodatkowych treści na wyświetlaczu na okładce skierowanym do innych użytkowników. Na przykład na wyświetlaczu na okładce może być widoczny podgląd z aparatu osobie, która jest fotografowana lub nagrywana.
Konfiguracja urządzenia
Aby umożliwić implementację funkcji składania, producenci OEM muszą:
Skonfiguruj stany urządzeń w usłudze
device_state_configuration.xml
, których ma używaćDeviceStateManagerService
. Więcej informacji znajdziesz w sekcjiDeviceStateProviderImpl.java
.Jeśli domyślna implementacja
DeviceStateProvider
lubDeviceStatePolicy
nie jest odpowiednia dla danego urządzenia, można użyć implementacji niestandardowej.W przypadku urządzeń składanych, które obsługują tryb otwarty lub płaski, w polu
com.android.internal.R.array.config_openDeviceStates
podaj odpowiednie identyfikatory stanów.W przypadku urządzeń składanych, które obsługują stan złożenia, wymień odpowiednie identyfikatory stanów w pliku
com.android.internal.R.array.config_foldedDeviceStates
.W przypadku urządzeń składanych, które umożliwiają złożenie do połowy (zawias jest otwarty w połowie jak w laptopie), wymień odpowiednie stany w polu
com.android.internal.R.array.config_halfFoldedDeviceStates
.W przypadku urządzeń obsługujących tryb wyświetlacza tylnego:
- Wyświetl odpowiednie stany w polu
com.android.internal.R.array.config_rearDisplayDeviceStates
dla:DeviceStateManager
. - W pliku
com.android.internal.R.string.config_rearDisplayPhysicalAddress
określ adres fizycznego wyświetlacza tylnego. - W elementach
com.android.internal.R.integer.config_deviceStateRearDisplay
określ identyfikator stanu, który ma być używany przez rozszerzenia. - Dodaj identyfikator stanu w
com.android.internal.R.array.config_deviceStatesAvailableForAppRequests
, aby udostępnić go aplikacjom.
- Wyświetl odpowiednie stany w polu
Na Androidzie 14 na urządzeniach obsługujących tryb podwójnego (jednoczesnego) wyświetlania:
- Ustaw
com.android.internal.R.bool.config_supportsConcurrentInternalDisplays
natrue
. - Podaj fizyczny wyświetlany adres tylnego wyświetlacza w polu
com.android.internal.R.config_deviceStateConcurrentRearDisplay
. - Określ identyfikator stanu w zasadzie
com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay
, który ma być używany przez rozszerzenia, jeśli ma być on dostępny dla aplikacji. - Dodaj identyfikator stanu w polu
com.android.internal.R.array.config_deviceStatesAvailableForAppRequests
, aby udostępnić go aplikacjom.
- Ustaw
Weryfikacja
Producenci OEM muszą sprawdzić swoje implementacje, aby zapewnić oczekiwane działanie w typowych scenariuszach. Testy CTS i testy za pomocą Jetpack WindowManager są dostępne dla OEM-ów do testowania implementacji.
Testy CTS
Aby przeprowadzić testy CTS, zobacz Przeprowadzanie testów CTS. Testy CTS dotyczące Jetpack WindowManager są dostępne w sekcji cts/tests/framework/base/windowmanager/jetpack/
.
Nazwa modułu testowego to CtsWindowManagerJetpackTestCases
.
Testy WindowManager
Aby pobrać testy Jetpack WindowManager, postępuj zgodnie z instrukcjami dotyczącymi Androida Jetpacka.
Testy znajdują się w bibliotece okien w module window:window
: window/window/src/androidTest/
.
Aby uruchomić testy urządzenia dla modułu window:window
w wierszu poleceń, wykonaj te czynności:
- Podłącz urządzenie z włączonymi opcjami programisty i debugowaniem USB.
- Zezwól komputerowi na debugowanie urządzenia.
- Otwórz powłokę w katalogu głównym repozytorium androidx.
- Zmień katalog na
framework/support
. - Uruchom to polecenie:
./gradlew window:window:connectedAndroidTest
. - Przeanalizuj wyniki.
Aby uruchomić testy w Android Studio, wykonaj te czynności:
- Otwórz Android Studio.
- Podłącz urządzenie z włączonymi opcjami programisty i debugowaniem USB.
- Zezwól komputerowi na debugowanie urządzenia.
- Przejdź do testu w bibliotece okien modułu okna.
- Otwórz klasę testową i uruchom ją za pomocą zielonych strzałek po prawej stronie edytora.
Możesz też utworzyć w Android Studio konfigurację, aby uruchomić metodę testową, klasę testową lub wszystkie testy w module.
Wyniki można analizować ręcznie, sprawdzając dane wyjściowe powłoki. Niektóre testy są pomijane, jeśli urządzenie nie spełnia określonych założeń. Wyniki są zapisywane w standardowej lokalizacji, a analitycy mogą napisać skrypt, który zautomatyzuje analizę wyników.