Bu ekrana özel alanlarda yapılan güncellemeler aşağıda verilmiştir:
- Etkinlikleri ve gösterileri yeniden boyutlandırma
- Ekran boyutları ve en boy oranları
- Politikaları görüntüle
- Pencere ayarlarını görüntüle
- Statik ekran tanımlayıcıları
- İkiden fazla ekranın kullanılması
- Ekran başına odaklama
Etkinlikleri ve ekranları yeniden boyutlandırın
Bir uygulamanın çoklu pencere modunu veya yeniden boyutlandırmayı desteklemeyebileceğini belirtmek için etkinlikler resizeableActivity=false
özelliğini kullanır. Etkinlikler yeniden boyutlandırıldığında uygulamaların karşılaştığı yaygın sorunlar şunlardır:
- Bir aktivite, uygulamadan veya başka bir görsel olmayan bileşenden farklı bir konfigürasyona sahip olabilir. Yaygın bir hata, ekran metriklerini uygulama bağlamından okumaktır. Döndürülen değerler, bir etkinliğin görüntülendiği görünür alan metriklerine göre ayarlanmayacaktır.
- Bir etkinlik, örnek durumunu kaydetmeden yeniden boyutlandırma ve çökme işlemlerini gerçekleştiremeyebilir, bozuk bir kullanıcı arayüzü görüntüleyemeyebilir veya yeniden başlatma nedeniyle durumu kaybedemeyebilir.
- Bir uygulama, çoklu pencerede girişi bozabilecek mutlak giriş koordinatlarını (pencere konumuna göre olanlar yerine) kullanmaya çalışabilir.
Android 7'de (ve üzeri), bir uygulama her zaman tam ekran modunda çalışacak şekilde resizeableActivity=false
olarak ayarlanabilir. Bu durumda platform, yeniden boyutlandırılamayan etkinliklerin bölünmüş ekrana geçmesini engeller. Kullanıcı zaten bölünmüş ekran modundayken başlatıcıdan yeniden boyutlandırılamayan bir etkinliği çağırmaya çalışırsa, platform bölünmüş ekran modundan çıkar ve yeniden boyutlandırılamayan etkinliği tam ekran modunda başlatır.
Bu özelliği bildirimde açıkça false
olarak ayarlayan uygulamalar, uyumluluk modu uygulanmadığı sürece çoklu pencere modunda başlatılmamalıdır:
- Tüm etkinlikleri ve etkinlik dışı bileşenleri içeren sürece aynı konfigürasyon uygulanır.
- Uygulanan yapılandırma, uygulama uyumlu ekranlar için CDD gereksinimlerini karşılar.
Android 10'da platform, yeniden boyutlandırılamayan etkinliklerin bölünmüş ekran moduna geçmesini hâlâ engelliyor ancak etkinlik sabit bir yön veya en boy oranı bildirmişse bunlar geçici olarak ölçeklendirilebilir. Aksi takdirde etkinlik, Android 9 ve önceki sürümlerde olduğu gibi ekranın tamamını dolduracak şekilde yeniden boyutlandırılır.
Varsayılan uygulama aşağıdaki politikayı uygular:
android:resizeableActivity
özelliği kullanılarak çoklu pencereyle uyumsuz olduğu bildirilen bir etkinlik ve bu etkinlik aşağıda açıklanan koşullardan birini karşıladığında, uygulanan ekran yapılandırmasının değişmesi gerektiğinde etkinlik ve süreç orijinal yapılandırmayla kaydedilir. ve kullanıcıya, güncellenmiş ekran yapılandırmasını kullanmak üzere uygulama sürecini yeniden başlatma olanağı sağlanır.
-
android:screenOrientation
uygulaması aracılığıyla sabit yönlendirme - Uygulama, API düzeyini hedefleyerek varsayılan maksimum veya minimum en boy oranına sahiptir veya en boy oranını açıkça beyan eder
Bu şekil, bildirilen en boy oranına sahip, yeniden boyutlandırılamayan bir etkinliği görüntüler. Cihazı katlarken, uygun posta kutusu kullanılarak en boy oranı korunurken pencere alana sığacak şekilde küçültülür. Ayrıca aktiviteye ait görüntüleme alanı her değiştiğinde kullanıcıya aktiviteyi yeniden başlatma seçeneği sunulur.
Cihazı açarken etkinliğin yapılandırması, boyutu ve en boy oranı değişmez ancak etkinliği yeniden başlatma seçeneği görüntülenir.
resizeableActivity
ayarlanmadığında (veya true
olarak ayarlandığında), uygulama yeniden boyutlandırmayı tamamen destekler.
Uygulama
Sabit yönlendirmeye veya en boy oranına sahip, yeniden boyutlandırılamayan bir etkinliğe kodda boyut uyumluluk modu (SCM) adı verilir. Koşul ActivityRecord#shouldUseSizeCompatMode()
içinde tanımlanmıştır. Bir SCM etkinliği başlatıldığında, ekranla ilgili yapılandırma (boyut veya yoğunluk gibi) talep edilen geçersiz kılma yapılandırmasında sabitlenir, böylece etkinlik artık geçerli ekran yapılandırmasına bağlı değildir.
SCM etkinliği ekranın tamamını dolduramazsa yukarıya hizalanır ve yatay olarak ortalanır. Etkinlik sınırları AppWindowToken#calculateCompatBoundsTransformation()
tarafından hesaplanır.
Bir SCM etkinliği kapsayıcısından farklı bir ekran yapılandırması kullandığında (örneğin, ekran yeniden boyutlandırıldığında veya etkinlik başka bir ekrana taşındığında), ActivityRecord#inSizeCompatMode()
doğrudur ve SizeCompatModeActivityController
(Sistem kullanıcı arayüzünde) süreci göstermek için geri aramayı alır yeniden başlat düğmesi.
Ekran boyutları ve en boy oranları
Android 10, yüksek oranlı uzun ve ince ekranlardan 1:1 oranlarına kadar yeni en boy oranları için destek sağlıyor. Uygulamalar, işleyebilecekleri ekranın ApplicationInfo#maxAspectRatio
ve ApplicationInfo#minAspectRatio
değerlerini tanımlayabilir.
Şekil 1. Android 10'da desteklenen örnek uygulama oranları
Cihaz uygulamalarında, Android 9'un gerektirdiğinden daha küçük ve daha düşük boyutlara ve çözünürlüklere sahip ikincil ekranlar bulunabilir (minimum 2,5 inç genişlik veya yükseklik, en küçük smallestScreenWidth
için minimum 320 DP), ancak yalnızca bu küçük ekranları desteklemeyi tercih eden etkinlikler kullanılabilir. oraya yerleştirildi.
Uygulamalar, hedef görüntüleme boyutuna eşit olandan daha küçük bir desteklenen minimum boyut bildirerek bu seçeneği etkinleştirebilir. Bunu yapmak için AndroidManifest'teki android:minHeight
ve android:minWidth
etkinlik düzeni niteliklerini kullanın.
Politikaları görüntüle
Android 10, belirli görüntüleme politikalarını PhoneWindowManager
varsayılan WindowManagerPolicy
uygulamasından ayırarak ekran başına sınıflara taşır, örneğin:
- Görüntü durumu ve döndürme
- Bazı tuşlar ve hareket olayı takibi
- Sistem kullanıcı arayüzü ve dekorasyon pencereleri
Android 9'da (ve daha eski sürümlerde), PhoneWindowManager
sınıfı görüntüleme politikalarını, durumu ve ayarları, döndürmeyi, dekorasyon penceresi çerçevesi izlemeyi ve daha fazlasını yönetiyordu. Android 10, DisplayRotation
taşınan rotasyon izleme dışında bunların çoğunu DisplayPolicy
sınıfına taşır.
Pencere ayarlarını görüntüle
Android 10'da, ekrana göre yapılandırılabilir pencereleme ayarı aşağıdakileri içerecek şekilde genişletildi:
- Varsayılan ekran pencereleme modu
- Aşırı tarama değerleri
- Kullanıcı döndürme ve döndürme modu
- Zorunlu boyut, yoğunluk ve ölçeklendirme modu
- İçerik kaldırma modu (ekran kaldırıldığında)
- Sistem dekorasyonları ve IME desteği
DisplayWindowSettings
sınıfı bu seçeneklere ilişkin ayarları içerir. Bir ayar her değiştirildiğinde, display_settings.xml
dosyasındaki /data
bölümünde diske kaydedilmeye devam edilir. Ayrıntılar için bkz. DisplayWindowSettings.AtomicFileStorage
ve DisplayWindowSettings#writeSettings()
. Cihaz üreticileri, cihaz yapılandırmaları için display_settings.xml
dosyasında varsayılan değerleri sağlayabilirler. Ancak dosya /data
konumunda saklandığından, silme işlemiyle silinirse dosyayı geri yüklemek için ek mantığa ihtiyaç duyulabilir.
Varsayılan olarak Android 10, ayarları sürdürürken bir ekranın tanımlayıcısı olarak DisplayInfo#uniqueId
kullanır. uniqueId
tüm ekranlar için doldurulmalıdır. Ayrıca fiziksel ve ağ ekranları için de stabildir. Ayrıca DisplayWindowSettings#mIdentifier
içinde ayarlanabilen, tanımlayıcı olarak fiziksel bir ekranın bağlantı noktasını kullanmak da mümkündür. Her yazma işleminde tüm ayarlar yazılır, böylece depolamadaki bir ekran girişi için kullanılan anahtarı güncellemek güvenli olur. Ayrıntılar için bkz. Statik ekran tanımlayıcıları .
Ayarlar, geçmiş nedenlerden dolayı /data
dizininde korunur. Başlangıçta, ekran döndürme gibi kullanıcı tarafından belirlenen ayarları sürdürmek için kullanılıyorlardı.
Statik ekran tanımlayıcıları
Android 9 (ve altı), çerçevedeki ekranlar için kararlı tanımlayıcılar sağlamıyordu. Sisteme bir ekran eklendiğinde, statik bir sayaç artırılarak o ekran için Display#mDisplayId
veya DisplayInfo#displayId
oluşturuldu. Sistem aynı ekranı ekleyip çıkardığında farklı bir kimlik ortaya çıktı.
Bir cihazın önyüklemeden itibaren birden fazla ekranı varsa, zamanlamaya bağlı olarak ekranlara farklı tanımlayıcılar atanabilir. Android 9 (ve önceki sürümleri) DisplayInfo#uniqueId
öğesini içerse de, fiziksel ekranlar yerleşik ve harici ekranı temsil etmek üzere local:0
veya local:1
olarak tanımlandığından ekranlar arasında ayrım yapmak için yeterli bilgi içermiyordu.
Android 10, kararlı bir tanımlayıcı eklemek ve yerel, ağ ve sanal ekranlar arasında ayrım yapmak için DisplayInfo#uniqueId
değerini değiştirir.
Ekran tipi | Biçim |
---|---|
Yerel | local:<stable-id> |
Ağ | network:<mac-address> |
Sanal | virtual:<package-name-and-name> |
uniqueId
güncellemelerine ek olarak DisplayInfo.address
, yeniden başlatmalarda kararlı olan bir ekran tanımlayıcısı olan DisplayAddress
içerir. Android 10'da DisplayAddress
, fiziksel ve ağ ekranlarını destekler. DisplayAddress.Physical
sabit bir ekran kimliği içerir ( uniqueId
ile aynı) ve DisplayAddress#fromPhysicalDisplayId()
ile oluşturulabilir.
Android 10 ayrıca bağlantı noktası bilgilerini almak için kullanışlı bir yöntem de sağlar ( Physical#getPort()
). Bu yöntem, ekranları statik olarak tanımlamak için çerçevede kullanılabilir. Örneğin, DisplayWindowSettings
kullanılır). DisplayAddress.Network
MAC adresini içerir ve DisplayAddress#fromMacAddress()
ile oluşturulabilir.
Bu eklemeler, cihaz üreticilerinin statik çoklu ekran kurulumlarındaki ekranları tanımlamasına ve fiziksel ekranlar için bağlantı noktaları gibi statik ekran tanımlayıcılarını kullanarak farklı sistem ayarlarını ve özelliklerini yapılandırmasına olanak tanır. Bu yöntemler gizlidir ve yalnızca system_server
içinde kullanılmak üzere tasarlanmıştır.
Bir HWC ekran kimliği verildiğinde (opak olabilir ve her zaman kararlı olmayabilir), bu yöntem, ekranın EDID blobunun yanı sıra, ekran çıkışı için fiziksel bir konektörü tanımlayan (platforma özel) 8 bitlik bağlantı noktası numarasını döndürür. SurfaceFlinger, çerçeveye sunulan kararlı 64 bit ekran kimliklerini oluşturmak için EDID'den üretici veya model bilgilerini çıkarır. Bu yöntem desteklenmiyorsa veya hata veriyorsa SurfaceFlinger, yukarıda açıklandığı gibi DisplayInfo#address
boş olduğu ve DisplayInfo#uniqueId
sabit kodlandığı eski MD moduna geri döner.
Bu özelliğin desteklendiğini doğrulamak için şunu çalıştırın:
$ 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"
İkiden fazla ekran kullanma
Android 9'da (ve daha eski sürümlerde), SurfaceFlinger ve DisplayManagerService
, 0 ve 1 sabit kodlu kimliklere sahip en fazla iki fiziksel ekranın varlığını varsaydı.
Android 10'dan başlayarak SurfaceFlinger, sabit ekran kimlikleri oluşturmak için bir Donanım Oluşturucu (HWC) API'sinden yararlanabilir ve bu da isteğe bağlı sayıda fiziksel ekranı yönetmesine olanak tanır. Daha fazla bilgi edinmek için bkz. Statik ekran tanımlayıcıları .
Çerçeve, SurfaceControl#getPhysicalDisplayIds
veya bir DisplayEventReceiver
hotplug olayından 64 bit ekran kimliğini aldıktan sonra SurfaceControl#getPhysicalDisplayToken
aracılığıyla fiziksel bir ekran için IBinder
belirtecini arayabilir.
Android 10'da (ve daha eski sürümlerde), birincil dahili ekran TYPE_INTERNAL
ve bağlantı türünden bağımsız olarak tüm ikincil ekranlar TYPE_EXTERNAL
olarak işaretlenir. Bu nedenle, ek dahili ekranlar harici olarak değerlendirilir. Geçici bir çözüm olarak, HWC biliniyorsa ve bağlantı noktası tahsis mantığı öngörülebilirse, cihaza özgü kod DisplayAddress.Physical#getPort
hakkında varsayımlarda bulunabilir.
Bu sınırlama Android 11'de (ve üzeri) kaldırılmıştır.
- Android 11'de önyükleme sırasında bildirilen ilk ekran birincil ekrandır. Bağlantı türü (dahili veya harici) önemli değildir. Ancak birincil ekranın bağlantısının kesilemeyeceği doğrudur ve bunun pratikte dahili bir ekran olması gerektiği sonucu çıkar. Bazı katlanabilir telefonların birden fazla dahili ekrana sahip olduğunu unutmayın.
- İkincil ekranlar, bağlantı türlerine bağlı olarak
Display.TYPE_INTERNAL
veyaDisplay.TYPE_EXTERNAL
(önceden sırasıylaDisplay.TYPE_BUILT_IN
veDisplay.TYPE_HDMI
olarak biliniyordu) olarak doğru şekilde kategorize edilir.
Uygulama
Android 9 ve önceki sürümlerde ekranlar 32 bit kimliklerle tanımlanır; burada 0 dahili ekran, 1 harici ekran, [2, INT32_MAX]
HWC sanal ekranlardır ve -1 geçersiz bir ekranı veya HWC olmayan bir ekranı temsil eder. sanal ekran.
Android 10'dan itibaren ekranlara sabit ve kalıcı kimlikler veriliyor; bu, SurfaceFlinger ve DisplayManagerService
ikiden fazla ekranı izlemesine ve daha önce görülen ekranları tanımasına olanak tanıyor. HWC, IComposerClient.getDisplayIdentificationData
destekliyorsa ve ekran tanımlama verileri sağlıyorsa SurfaceFlinger, EDID yapısını ayrıştırır ve fiziksel ve HWC sanal ekranlar için kararlı 64 bit ekran kimlikleri ayırır. Kimlikler, boş değerin geçersiz bir ekranı veya HWC olmayan sanal ekranı temsil ettiği bir seçenek türü kullanılarak ifade edilir. HWC desteği olmadan SurfaceFlinger, en fazla iki fiziksel ekranla eski davranışa geri döner.
Ekran başına odaklama
Aynı anda tek tek ekranları hedefleyen birden fazla giriş kaynağını desteklemek için Android 10, ekran başına en fazla bir tane olmak üzere birden fazla odaklanmış pencereyi destekleyecek şekilde yapılandırılabilir. Bu, yalnızca birden fazla kullanıcının aynı anda aynı cihazla etkileşimde bulunduğu ve Android Automotive gibi farklı giriş yöntemleri veya cihazları kullandığı özel cihaz türleri için tasarlanmıştır.
Bu özelliğin, çoklu ekranlı cihazlar veya masaüstü benzeri deneyimler için kullanılanlar da dahil olmak üzere normal cihazlar için etkinleştirilmemesi önemle tavsiye edilir. Bunun temel nedeni, kullanıcıların hangi pencerenin giriş odağına sahip olduğunu merak etmelerine neden olabilecek bir güvenlik sorunudur.
Kullanıcının bir metin giriş alanına güvenli bilgiler girdiğini, örneğin bir bankacılık uygulamasında oturum açtığını veya hassas bilgiler içeren bir metin girdiğini hayal edin. Kötü amaçlı bir uygulama, bir etkinliğin yürütüleceği, ayrıca metin giriş alanına sahip, sanal bir ekran dışı görüntü oluşturabilir. Yasal ve kötü amaçlı faaliyetlerin odağı vardır ve her ikisi de etkin bir giriş göstergesi (yanıp sönen imleç) görüntüler.
Ancak, klavyeden (donanım veya yazılım) gelen girdi yalnızca en üstteki etkinliğe (en son başlatılan uygulamaya) girildiğinden, kötü amaçlı bir uygulama, gizli bir sanal ekran oluşturarak, yazılım klavyesi kullanılırken bile kullanıcı girdisini ele geçirebilir. birincil cihaz ekranında.
Ekran başına odağı ayarlamak için com.android.internal.R.bool.config_perDisplayFocusEnabled
kullanın.
Uyumluluk
Sorun: Android 9 ve önceki sürümlerde, sistemdeki en fazla bir pencere aynı anda odaklanıyor.
Çözüm: Aynı süreçten iki pencerenin odaklanacağı nadir durumlarda, sistem yalnızca Z sırasında daha yüksek olan pencereye odaklanma sağlar. Bu kısıtlama, Android 10'u hedefleyen uygulamalar için kaldırılmıştır; bu noktada, birden fazla pencerenin aynı anda odaklanmasını destekleyebilmeleri beklenir.
Uygulama
WindowManagerService#mPerDisplayFocusEnabled
bu özelliğin kullanılabilirliğini kontrol eder. ActivityManager
artık bir değişkende global izleme yerine ActivityDisplay#getFocusedStack()
kullanılıyor. ActivityDisplay#getFocusedStack()
değeri önbelleğe almak yerine Z sırasına göre odağı belirler. Bu, yalnızca tek bir kaynağın, WindowManager'ın, etkinliklerin Z sırasını izlemesine ihtiyaç duyması içindir.
ActivityStackSupervisor#getTopDisplayFocusedStack()
sistemdeki en üstteki odaklanmış yığının tanımlanmasının gerekli olduğu durumlar için benzer bir yaklaşım benimser. Yığınlar yukarıdan aşağıya doğru hareket ettirilerek ilk uygun yığın aranır.
InputDispatcher
artık birden fazla odaklanmış pencereye sahip olabilir (ekran başına bir tane). Bir giriş olayı ekrana özelse ilgili ekrandaki odaklanılan pencereye gönderilir. Aksi takdirde, kullanıcının en son etkileşimde bulunduğu ekran olan odaklanılmış ekrandaki odaklanılan pencereye gönderilir.
Bkz. InputDispatcher::mFocusedWindowHandlesByDisplay
ve InputDispatcher::setFocusedDisplay()
. Odaklanmış uygulamalar ayrıca NativeInputManager::setFocusedApplication()
aracılığıyla inputManagerService'de ayrı olarak güncellenir.
WindowManager
odaklanılan pencereler ayrıca ayrı olarak izlenir. DisplayContent#mCurrentFocus
ve DisplayContent#mFocusedApp
ve ilgili kullanımlara bakın. İlgili odak izleme ve güncelleme yöntemleri WindowManagerService
DisplayContent
taşındı.