Poniżej znajdziesz informacje o zmianach w obszarach związanych z wyświetlaniem:
- Zmiana rozmiaru aktywności i wyświetlaczy
- Rozmiary i formaty obrazu
- Zasady wyświetlania
- Ustawienia okna wyświetlacza
- Statyczne identyfikatory displayowe
- Korzystanie z więcej niż 2 ekranów
- Kierowanie na wyświetlacz
Zmień rozmiar aktywności i wyświetlaczy
Aby wskazać, że aplikacja może nie obsługiwać trybu wielu okien ani zmiany rozmiaru,
aktywności używają atrybutu resizeableActivity=false
. Powszechny
Przy zmianie rozmiaru aktywności aplikacje napotykają następujące problemy:
- Aktywność może mieć inną konfigurację niż aplikacja niewizualne. Częstym błędem jest odczytywanie danych o wyświetlaniu z aplikacji i dodaje kontekst. Zwrócone wartości nie będą dostosowywane do danych dotyczących widocznych obszarów w w którym ma być wyświetlana aktywność.
- Aktywność może nie obsługiwać zmiany rozmiaru ani awarii, wyświetlać zniekształcony interfejs użytkownika. lub utracą stan z powodu ponownego uruchomienia bez zapisania stanu instancji.
- Aplikacja może próbować użyć bezwzględnych współrzędnych wejściowych (zamiast tych względem pozycji okna), co może spowodować uszkodzenie danych wejściowych tryb wielu okien.
W Androidzie 7 (lub nowszym) aplikację można skonfigurować
resizeableActivity=false
, aby zawsze działać w trybie pełnoekranowym. W
W tym przypadku platforma zapobiega rozdzielaniu działań, których nie można zmienić,
ekranu. Jeśli użytkownik spróbuje wywołać z programu uruchamiającego aktywność, której nie można zmienić
gdy platforma jest już w trybie podzielonego ekranu, wyjdzie z niego,
uruchamia aktywność, której nie można zmienić, w trybie pełnoekranowym.
Aplikacje, które wprost ustawiają ten atrybut na false
w
pliku manifestu nie można uruchamiać w trybie wielu okien, chyba że
stosowany jest tryb:
- Ta sama konfiguracja jest stosowana do procesu, który obejmuje wszystkie działania i komponenty bez aktywności.
- Zastosowana konfiguracja spełnia wymagania CDD dotyczące zgodności z aplikacjami i wyświetlacze.
W Androidzie 10 platforma nadal uniemożliwia aktywności, których nie można zmienić, z trybu podzielonego ekranu. tymczasowo skalowane, jeśli aktywność ma zadeklarowaną stałą orientację lub aspekt współczynnik proporcji. W przeciwnym razie aktywność zmienia rozmiar, aby wypełnić cały ekran – tak jak na Androidzie. 9 i niższych.
Domyślna implementacja stosuje te zasady:
Gdy aktywność zadeklarowana jako niezgodna z trybem wielu okien przez
użycia atrybutu android:resizeableActivity
oraz gdy to
aktywność spełnia jeden z warunków opisanych poniżej, a następnie po zastosowaniu zastosowania
musi zmienić konfigurację ekranu, aktywność i proces są zapisywane
do oryginalnej konfiguracji, a użytkownik ma możliwość ponownego uruchomienia
proces aplikacji, aby używał zaktualizowanej konfiguracji ekranu.
- ma stałą orientację dzięki zastosowaniu
android:screenOrientation
- Aplikacja ma domyślny maksymalny lub minimalny współczynnik proporcji zgodnie z kierowaniem na poziom interfejsu API lub wyraźnie deklaruje format obrazu
Ta ilustracja pokazuje aktywność, której nie można zmienić, o zadeklarowanym współczynniku proporcji. Po złożeniu urządzenia okno jest pomniejszane, aby pasowało do obszaru. z zachowaniem proporcji obrazu za pomocą odpowiednich czarnych pasów. Dodatkowo opcja ponownego uruchamiania jest udostępniana użytkownikowi za każdym razem, gdy obszar wyświetlania aktywność zostanie zmieniona.
Po rozłożeniu urządzenia sprawdź konfigurację, rozmiar i format obrazu nie zmienia się, ale wyświetla się opcja ponownego uruchomienia aktywności.
Gdy zasada resizeableActivity
jest nieskonfigurowana (lub ma wartość
true
), aplikacja w pełni obsługuje zmianę rozmiaru.
Implementacja
Aktywność bez możliwości zmiany rozmiaru o stałej orientacji lub współczynniku proporcji to tzw.
trybu zgodności rozmiaru (SCM). Warunek jest zdefiniowany w
ActivityRecord#shouldUseSizeCompatMode()
Gdy działanie SCM jest
konfiguracji dotyczącej ekranu (np. rozmiaru lub gęstości) jest stała
w żądanej konfiguracji zastępowania, więc aktywność nie jest już zależna
w bieżącej konfiguracji wyświetlacza.
Jeśli działanie SCM nie może wypełnić całego ekranu, jest wyrównane do góry i
wyśrodkowany w poziomie. Granice aktywności są obliczane według wzoru
AppWindowToken#calculateCompatBoundsTransformation()
Gdy aktywność w SCM używa innej konfiguracji ekranu niż jej
kontener (np. zmieniono rozmiar wyświetlacza lub działanie zostało przeniesione do innego
), ActivityRecord#inSizeCompatMode()
ma wartość prawda i
SizeCompatModeActivityController
(w interfejsie systemu) otrzymuje
wywołanie zwrotne, aby wyświetlić przycisk ponownego uruchamiania procesu.
Rozmiary i formaty obrazu
Android 10 obsługuje nowe formaty obrazu
od wysokich współczynników długich i cienkich ekranów do 1:1. Aplikacje mogą zdefiniować
ApplicationInfo#maxAspectRatio
i ApplicationInfo#minAspectRatio
ekranu,
które da się radzić sobie z czymś.
Rysunek 1. Przykładowe formaty aplikacji obsługiwane na Androidzie 10
Implementacje urządzeń mogą mieć ekrany dodatkowe o różnych rozmiarach i
rozdzielczości mniejszych niż wymagane przez Androida 9 i mniejszych (minimum 2, 5
cal szerokości lub wysokości, minimum 320 DP dla jednostki reklamowej smallestScreenWidth
),
ale można umieszczać tylko te aktywności,
które obsługują te małe ekrany
tam.
Aby udostępnić aplikację, zadeklaruj minimalny obsługiwany rozmiar, który jest mniejszy niż
lub równy docelowemu rozmiarowi wyświetlacza. Korzystaj z dokumentów android:minHeight
oraz
Atrybuty układu aktywności android:minWidth
w
AndroidManifest.
Zasady wyświetlania
Android 10 oddziela i przesuwa niektóre wyświetlacze
zasady z domyślnej implementacji WindowManagerPolicy
w
PhoneWindowManager
do poszczególnych klas, takich jak:
- Stan wyświetlania i obrót
- Niektóre klawisze i śledzenie zdarzeń ruchu
- Interfejs systemu i okna dekoracji
W Androidzie 9 (i starszych wersjach) obsługiwana jest klasa PhoneWindowManager
zasady wyświetlania, stan i ustawienia, obrót, ramka okna dekoracji
śledzenia konwersji i nie tylko. Android 10 wprowadza większość tych zmian
klasy DisplayPolicy
, z wyjątkiem śledzenia rotacji, które ma
został przeniesiony do DisplayRotation
.
Ustawienia okna wyświetlacza
W Androidzie 10 opcje konfiguracji dla poszczególnych wyświetlaczy rozszerzyliśmy ustawienie okienowania na:
- Domyślny tryb okna wyświetlania
- Nadmiarowość obrazu
- Tryb rotacji i rotacji użytkowników
- Wymuszony rozmiar, gęstość i tryb skalowania
- Tryb usuwania treści (po wyjęciu wyświetlacza)
- Obsługa dekoracji systemu i IME
Zajęcia DisplayWindowSettings
zawierają te ustawienia:
. Są one zapisywane na dysku na /data
partycji w
display_settings.xml
po każdej zmianie ustawienia. Dla:
Więcej informacji: DisplayWindowSettings.AtomicFileStorage
i
DisplayWindowSettings#writeSettings()
Producenci urządzeń mogą
podać domyślne wartości dla urządzenia w display_settings.xml
konfiguracji. Plik znajduje się jednak w lokalizacji /data
,
przywrócenie danych w przypadku usunięcia przez funkcję czyszczenia może wymagać dodatkowych funkcji logicznych.
Domyślnie Android 10 używa
DisplayInfo#uniqueId
jako identyfikator wyświetlacza, który jest trwały
ustawienia. W przypadku wszystkich wyświetlaczy należy wypełnić pole uniqueId
. W
ale również na wyświetlaczach fizycznych i sieciowych. Możesz też
użyj portu fizycznego wyświetlacza jako identyfikatora, który można ustawić
DisplayWindowSettings#mIdentifier
Przy każdym zapisie wszystkie ustawienia
są zapisane, więc można bezpiecznie zaktualizować klucz używany do wyświetlania wpisu w
pamięci masowej. Więcej informacji:
Statyczne identyfikatory displayowe.
Ustawienia są zachowywane w katalogu /data
na potrzeby danych historycznych
. Początkowo służyły one do zachowywania ustawień użytkownika, takich jak:
obrót wyświetlacza.
Statyczne identyfikatory displayowe
Android 9 (i starsze wersje) nie udostępniał stabilnych identyfikatorów wyświetlaczy
platformy. Po dodaniu wyświetlacza do systemu
Poprzednia wartość „Display#mDisplayId
” lub „DisplayInfo#displayId
” to
generowanych dla danego wyświetlacza przez zwiększenie wartości licznika statycznego. Jeśli system
użytkownik dodał i usunął ten sam wyświetlacz, wyświetlił się inny identyfikator.
Jeśli po uruchomieniu urządzenia było dostępnych kilka wyświetlaczy, można je było
mają przypisane różne identyfikatory w zależności od czasu. Android 9 (oraz
wcześniej) obejmował(a) DisplayInfo#uniqueId
, miał za mało
aby rozróżniać ekrany, ponieważ fizyczne wyświetlacze były
określane jako local:0
lub local:1
, co reprezentuje
z wbudowanym i zewnętrznym wyświetlaczem.
Zmiany w Androidzie 10: DisplayInfo#uniqueId
do dodania stabilnego identyfikatora oraz odróżniania
lokalnych, sieciowych i sieciowych
wirtualnych wyświetlaczy.
Typ wyświetlacza | Format |
---|---|
Lokalne | local:<stable-id> |
Sieć | network:<mac-address> |
Wirtualna | virtual:<package-name-and-name> |
Oprócz aktualizacji usługi uniqueId
,
DisplayInfo.address
zawiera DisplayAddress
,
identyfikator wyświetlania, który jest niezmienny po ponownym uruchomieniu. Na Androidzie
10, DisplayAddress
obsługuje fizyczne
i wyświetlacze sieciowe. DisplayAddress.Physical
zawiera stabilny ciąg
wyświetlany identyfikator (taki sam jak w polu uniqueId
) i można go utworzyć za pomocą
DisplayAddress#fromPhysicalDisplayId()
Android 10 zapewnia też wygodną metodę
informacje o porcie (Physical#getPort()
). Tej metody można używać w
statyczną podstawę do
statycznego identyfikowania wyświetlaczy. Jest używane na przykład w
DisplayWindowSettings
). DisplayAddress.Network
zawiera adres MAC i można go utworzyć za pomocą
DisplayAddress#fromMacAddress()
Te dodatki pozwalają producentom urządzeń rozpoznawać wyświetlacze w statycznym układzie.
konfiguracji na kilku wyświetlaczach oraz do konfigurowania różnych ustawień i funkcji systemu
za pomocą statycznych identyfikatorów wyświetlania, np. portów do fizycznego wyświetlacza. Te
metody są ukryte i są przeznaczone do użycia wyłącznie
system_server
Po przeanalizowaniu identyfikatora wyświetlania HWC (który może być nieprzezroczysty i nie zawsze stabilny), funkcja
zwraca (właściwy dla platformy) 8-bitowy numer portu, który identyfikuje
fizyczne złącze wyjścia wyświetlacza oraz obiekt blob EDID wyświetlacza.
SurfaceFlinger wyodrębnia informacje o producencie lub modelu z EDID do
pozwala wygenerować stabilne 64-bitowe identyfikatory wyświetlania dostępne dla platformy. Jeśli ta metoda
nie jest obsługiwany lub występują błędy, SurfaceFlinger wraca do starszego trybu MD,
gdzie DisplayInfo#address
ma wartość null, a
Parametr DisplayInfo#uniqueId
jest zakodowany na stałe, jak opisano powyżej.
Aby sprawdzić, czy ta funkcja jest obsługiwana, uruchom polecenie:
$ dumpsys SurfaceFlinger --display-id # Example output. Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32" Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i" Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"
Korzystanie z więcej niż 2 wyświetlaczy
Android 9 (i starsze wersje), SurfaceFlinger i DisplayManagerService
przyjęto, że istnieją maksymalnie 2 wyświetlacze fizyczne o zakodowanych na stałe identyfikatorami 0.
oraz 1.
Począwszy od Androida 10, SurfaceFlinger może wykorzystać Interfejs Hardware Composer (HWC) API do generowania stabilnych identyfikatorów wyświetlania, który umożliwia zarządzanie dowolną liczbę fizycznych wyświetlaczy. Więcej informacji: Statyczne identyfikatory displayowe.
Platforma może wyszukać token IBinder
dla
wyświetlić przez SurfaceControl#getPhysicalDisplayToken
po uzyskaniu
64-bitowy identyfikator wyświetlania z SurfaceControl#getPhysicalDisplayIds
lub
z wydarzenia Hotplug (DisplayEventReceiver
).
W Androidzie 10 (i starszych) podstawowy ekran wewnętrzny jest
TYPE_INTERNAL
i wszystkie wyświetlacze dodatkowe są oznaczone jako TYPE_EXTERNAL
niezależnie od typu połączenia. Dlatego dodatkowe ekrany wewnętrzne są traktowane jako zewnętrzne.
Aby obejść ten problem, kod na urządzeniu może generować założenia dotyczące
DisplayAddress.Physical#getPort
, jeśli usługa HWC jest znana, a przydział portów jest znany
że logika jest przewidywalna.
To ograniczenie zostało usunięte w Androidzie 11 (i nowszych).
- W Androidzie 11 pierwszym wyświetlaczem zgłoszonym podczas uruchamiania jest głównym wyświetlaczu. Typ połączenia (wewnętrzne lub zewnętrzne) jest nieistotny. Prawda jest jednak taka, że nie można odłączyć głównego wyświetlacza, zgodnie z tym w praktyce musi to być ekran wewnętrzny. Pamiętaj, że niektóre składane telefony mają kilka wewnętrznych wyświetlaczy.
- Wyświetlacze dodatkowe są prawidłowo klasyfikowane jako
Display.TYPE_INTERNAL
lubDisplay.TYPE_EXTERNAL
(dawniejDisplay.TYPE_BUILT_IN
) iDisplay.TYPE_HDMI
) w zależności od ich typu połączenia.
Implementacja
W Androidzie 9 i starszych ekranach wyświetlane są identyfikatory 32-bitowe,
gdzie 0 to wyświetlacz wewnętrzny, 1 to wyświetlacz zewnętrzny, [2, INT32_MAX]
to wyświetlacze wirtualne HWC, a -1 oznacza nieprawidłowy wyświetlacz lub wyświetlacz niewirtualny.
Począwszy od Androida 10 wyświetlacze będą miały stabilną wersję
i trwałe identyfikatory, które umożliwiają SurfaceFlinger i DisplayManagerService
śledzić więcej niż dwa wyświetlacze i rozpoznawać wcześniej wyświetlane wyświetlacze. Jeśli HWC
obsługuje IComposerClient.getDisplayIdentificationData
i udostępnia wyświetlacz
danych identyfikacyjnych, SurfaceFlinger analizuje strukturę EDID i przydziela stabilne
64-bitowe identyfikatory wyświetlaczy fizycznych i wirtualnych ekranów HWC. Identyfikatory są wyrażone za pomocą
typ opcji, w którym wartość null oznacza nieprawidłowe wyświetlanie lub wirtualny wyświetlacz inny niż HWC
wyświetlacz. Bez obsługi HWC SurfaceFlinger wraca do starszego sposobu działania z
z większości 2 ekranów.
Zaznaczenie według wyświetlacza
Do obsługi kilku źródeł danych wejściowych kierowanych na poszczególne wyświetlacze w tym samym czasie Android 10 można skonfigurować tak, aktywne okna, najwyżej jedno na wyświetlacz. Jest przeznaczone wyłącznie do stosowania specjalnych typów urządzeń, gdy wielu użytkowników korzysta z tego samego urządzenia czasu i używać różnych metod wprowadzania lub urządzeń, np. Androida Motoryzacja.
Zdecydowanie zalecamy, aby ta funkcja nie była włączona w przypadku na zwykłych urządzeniach, w tym urządzeniach wieloekranowych i takich jak komputery. i aplikacji. Wynika to przede wszystkim z obaw związanych z bezpieczeństwem, które mogą powodować aby się dowiedzieć, które okno ma zaznaczone dane wejściowe.
Wyobraź sobie, że użytkownik wpisuje bezpieczne informacje w polu tekstowym, np. logując się w aplikacji bankowej lub wpisując tekst, który zawiera poufne i informacjami o nich. Złośliwa aplikacja może utworzyć wirtualny wyświetlacz poza ekranem, który ma wykonać działanie, oraz pole do wprowadzania tekstu. Uzasadnione złośliwe działania są skupione i obydwa z nich pokazują aktywny wskaźnik (kursor migający).
Ponieważ jednak dane wejściowe z klawiatury (sprzętu lub oprogramowania) są wprowadzane w tylko najwyższą aktywność (czyli uruchomioną ostatnio aplikację), według tworząc ukryty wirtualny wyświetlacz, szkodliwa aplikacja może pobierać dane wejściowe użytkownika, a nawet w przypadku korzystania z klawiatury programowej na głównym wyświetlaczu.
Użyj formatu: com.android.internal.R.bool.config_perDisplayFocusEnabled
Zgodność
Problem: w Androidzie 9 i starszych wersjach maksymalnie jedno okno w danym momencie.
Rozwiązanie: w rzadkim przypadku, gdy 2 okien z programu ten sam proces, system zaznacza tylko okno, który znajduje się wyżej w porządku warstw. To ograniczenie zostało usunięte w przypadku aplikacji kierowanych na Androida 10. W takiej sytuacji prawdopodobnie obsługują wiele okien jednocześnie.
Implementacja
WindowManagerService#mPerDisplayFocusEnabled
kontroluje:
i dostępności tej funkcji. W języku: ActivityManager
Zamiast globalnego identyfikatora używany jest teraz ActivityDisplay#getFocusedStack()
śledzenie w zmiennej. ActivityDisplay#getFocusedStack()
określa fokus na podstawie kolejności podziału zamiast zapisywania wartości w pamięci podręcznej. Dzięki temu
tylko jedno źródło, WindowManager, potrzebuje śledzenia działań w kolejności na osi Z.
ActivityStackSupervisor#getTopDisplayFocusedStack()
zajmuje
podobne podejście w przypadkach, w których
najbardziej skupiony stos w systemie
musi być zidentyfikowana. Stosy są układane od góry do dołu w poszukiwaniu
pierwszy odpowiedni stos.
InputDispatcher
może teraz mieć wiele zaznaczonych okien
(jedna na wyświetlacz). Jeśli zdarzenie wejściowe jest specyficzne dla wyświetlania, jest wysyłane
do zaznaczonego okna na odpowiednim wyświetlaczu. W przeciwnym razie jest wysyłany
do zaznaczonego okna, na którym użytkownik widzi
użytkownik ostatnio kontaktował się z użytkownikiem.
Zobacz InputDispatcher::mFocusedWindowHandlesByDisplay
i
InputDispatcher::setFocusedDisplay()
Aktualizowane są też wybrane aplikacje
w).
NativeInputManager::setFocusedApplication()
W systemie WindowManager
zaznaczone okna są też śledzone oddzielnie.
Zobacz DisplayContent#mCurrentFocus
i
DisplayContent#mFocusedApp
i ich zastosowania. Powiązane elementy
Metody śledzenia i aktualizacji zostały przeniesione z
WindowManagerService
do DisplayContent
.