Çalışma zamanı kaynak kaplaması (RRO), çalışma zamanında bir hedef paketin kaynak değerlerini değiştiren bir pakettir. Örneğin, sistem görüntüsüne yüklenen bir uygulama, kaynağın değerine bağlı olarak davranışını değiştirebilir. Kaynak değerini derleme sırasında sabit kodlamak yerine, farklı bir bölüme yüklenen bir RRO, uygulama kaynaklarının değerlerini çalışma zamanında değiştirebilir.
RRO'lar etkinleştirilebilir veya devre dışı bırakılabilir. Bir RRO'nun kaynak değerlerini değiştirme yeteneğini değiştirmek için etkinleştirme/devre dışı bırakma durumunu program aracılığıyla ayarlayabilirsiniz. RRO'lar varsayılan olarak devre dışıdır (ancak statik RRO'lar varsayılan olarak etkindir).
Kaynakların üst üste bindirilmesi
Kaplamalar, kaplama paketinde tanımlanan kaynakları hedef pakette tanımlanan kaynaklarla eşleyerek çalışır. Bir uygulama hedef paketteki bir kaynağın değerini çözümlemeye çalıştığında bunun yerine hedef kaynağın eşlendiği yer paylaşımlı kaynağın değeri döndürülür.
Manifest'i ayarlama
Bir paket, <manifest>
etiketinin alt öğesi olarak <overlay>
etiketini içeriyorsa RRO paketi olarak kabul edilir.
Gerekli
android:targetPackage
özelliğinin değeri, RRO'nun kaplamayı amaçladığı paketin adını belirtir.İsteğe bağlı
android:targetName
özniteliğinin değeri, RRO'nun kaplamayı amaçladığı hedef paketin kaplanabilir kaynak alt kümesinin adını belirtir. Hedef, yerleştirilebilir bir kaynak kümesini tanımlamıyorsa bu özniteliğin mevcut olmaması gerekir.
Aşağıdaki kod AndroidManifest.xml
örneğini göstermektedir.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.overlay">
<application android:hasCode="false" />
<overlay android:targetPackage="com.example.target"
android:targetName="OverlayableResources"/>
</manifest>
Kaplamalar kodu kaplayamaz, dolayısıyla DEX dosyalarına sahip olamazlar. Ayrıca manifestteki <application
> etiketinin android:hasCode
özelliğinin false
olarak ayarlanması gerekir.
Kaynak haritasını tanımlama
Android 11 veya sonraki sürümlerde, yer paylaşımı kaynakları haritasını tanımlamak için önerilen mekanizma, yer paylaşımı paketinin res/xml
dizininde bir dosya oluşturmak, yer paylaşımı yapılması gereken hedef kaynakları ve bunların değiştirilme değerlerini numaralandırmak, ardından değerini ayarlamaktır. <overlay>
manifest etiketinin android:resourcesMap
niteliğini, kaynak eşleme dosyasına yapılan bir referansa yönlendirir.
Aşağıdaki kod örnek bir res/xml/overlays.xml
dosyasını gösterir.
<?xml version="1.0" encoding="utf-8"?>
<overlay xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Overlays string/config1 and string/config2 with the same resource. -->
<item target="string/config1" value="@string/overlay1" />
<item target="string/config2" value="@string/overlay1" />
<!-- Overlays string/config3 with the string "yes". -->
<item target="string/config3" value="@android:string/yes" />
<!-- Overlays string/config4 with the string "Hardcoded string". -->
<item target="string/config4" value="Hardcoded string" />
<!-- Overlays integer/config5 with the integer "42". -->
<item target="integer/config5" value="42" />
</overlay>
Aşağıdaki kod örnek bir yer paylaşımı bildirimini gösterir.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.overlay">
<application android:hasCode="false" />
<overlay android:targetPackage="com.example.target"
android:targetName="OverlayableResources"
android:resourcesMap="@xml/overlays"/>
</manifest>
Paketi oluşturma
Android 11 veya üzeri, Android Asset Packaging Tool 2'nin (AAPT2) aynı değere ( --no-resource-deduping
) sahip kaynakların yapılandırmalarını tekilleştirmeye çalışmasını ve varsayılan yapılandırmalar olmadan kaynakları kaldırmasını engelleyen kaplamalar için Soong derleme kuralını destekler ( --no-resource-removal
). Aşağıdaki kod örnek bir Android.bp
dosyasını gösterir.
runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
Kaynakları çözümleme
Bir hedef kaynak veya katman kaynağının, sorgulanan kaynak için tanımlanmış birden fazla konfigürasyonu varsa, kaynak çalışma zamanı, cihaz konfigürasyonunun konfigürasyonuyla en iyi eşleşen konfigürasyonun değerini döndürür. Hangi yapılandırmanın en iyi eşleşen yapılandırma olduğunu belirlemek için, yer paylaşımlı kaynak yapılandırmaları kümesini hedef kaynak yapılandırmaları kümesiyle birleştirin ve ardından normal kaynak çözümleme akışını izleyin (ayrıntılar için Android'in en iyi eşleşen kaynağı nasıl bulduğu bölümüne bakın).
Örneğin, bir yer paylaşımı drawable-en
drawable-en-port
için bir değer tanımlıyorsa, drawable-en-port
daha iyi bir eşleşmeye sahip olur, dolayısıyla drawable-en-port
hedef konfigürasyonunun değeri şöyle olur: çalışma zamanında seçilir. Tüm drawable-en
konfigürasyonları kaplamak için kaplamanın, hedefin tanımladığı her drawable-en
konfigürasyon için bir değer tanımlaması gerekir.
Kaplamalar, Android sürümleri arasında farklı davranışlarla kendi kaynaklarına referans verebilir.
Android 11 veya sonraki sürümlerde, her bir yer paylaşımının, hedef kaynak kimliği alanıyla veya diğer yer paylaşımı kaynak kimliği alanlarıyla örtüşmeyen kendi ayrılmış kaynak kimliği alanı vardır; bu nedenle, kendi kaynaklarına referans veren yer paylaşımları beklendiği gibi çalışır.
Android 10 veya önceki sürümlerde, kaplamalar ve hedef paketler aynı kaynak kimlik alanını paylaşır; bu da
@type/name
sözdizimini kullanarak kendi kaynaklarına başvurmaya çalıştıklarında çarpışmalara ve beklenmeyen davranışlara neden olabilir.
Kaplamaları etkinleştirme/devre dışı bırakma
Değişken kaplamaları etkinleştirmek ve devre dışı bırakmak için OverlayManager
API'sini kullanın ( Context#getSystemService(Context.OVERLAY_SERVICE)
kullanarak API arayüzünü alın). Bir yer paylaşımı yalnızca hedeflediği paket veya android.permission.CHANGE_OVERLAY_PACKAGES
iznine sahip bir paket tarafından etkinleştirilebilir. Bir katman etkinleştirildiğinde veya devre dışı bırakıldığında, yapılandırma değişikliği olayları hedef pakete yayılır ve hedef etkinlikler yeniden başlatılır.
Yerleştirilebilir kaynakları kısıtlama
Android 10 veya üzeri sürümlerde <overlayable>
XML etiketi, RRO'ların yer paylaşımına izin verdiği bir dizi kaynağı ortaya çıkarır. Aşağıdaki örnekte res/values/overlayable.xml
dosyası, string/foo
ve integer/bar
cihazın görünümünü temalandırmak için kullanılan kaynaklardır; Bu kaynakların yer paylaşımı için bir yer paylaşımının, yer paylaşımı yapılabilir kaynakların koleksiyonunu ada göre açıkça hedeflemesi gerekir.
<!-- The collection of resources for theming the appearance of the device -->
<overlayable name="ThemeResources">
<policy type="public">
<item type="string" name="foo/" />
<item type="integer" name="bar/" />
</policy>
...
</overlayable>
Bir APK birden fazla <overlayable>
etiketi tanımlayabilir, ancak her etiketin paket içinde benzersiz bir adı olmalıdır. Örneğin:
İki farklı paketin her ikisinin de
<overlayable name="foo">
tanımlaması tamamdır.Tek bir APK'nın iki
<overlayable name="foo">
bloğuna sahip olması uygun değildir.
Aşağıdaki kod, AndroidManifest.xml
dosyasındaki bir kaplama örneğini gösterir.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.theme.overlay">
<application android:hasCode="false" />
<!-- This overlay will override the ThemeResources resources -->
<overlay android:targetPackage="android" android:targetName="ThemeResources">
</manifest>
Bir uygulama bir <overlayable>
etiketi tanımladığında, bu uygulamayı hedefleyen yer paylaşımları:
targetName
belirtilmelidir.Yalnızca
<overlayable>
etiketi içinde listelenen kaynaklar kaplanabilir.Yalnızca bir
<overlayable>
adı hedefleyebilir.
Bindirilebilir kaynakları açığa çıkaran ancak belirli bir <overlayable>
etiketini hedeflemek için android:targetName
kullanmayan bir paketi hedefleyen bir kaplamayı etkinleştiremezsiniz.
Politikaları kısıtlama
Yerleştirilebilir kaynaklara kısıtlamalar uygulamak için <policy>
etiketini kullanın. type
özelliği, bir yer paylaşımının dahil edilen kaynakları geçersiz kılmak için hangi politikaları yerine getirmesi gerektiğini belirtir. Desteklenen türler aşağıdakileri içerir.
-
public
. Herhangi bir kaplama, kaynağı geçersiz kılabilir. -
system
. Sistem bölümündeki herhangi bir yer paylaşımı, kaynakları geçersiz kılabilir. -
vendor
. Satıcı bölümündeki herhangi bir yer paylaşımı, kaynakları geçersiz kılabilir. -
product
. Ürün bölümündeki herhangi bir kaplama, kaynakları geçersiz kılabilir. -
oem
. OEM bölümündeki herhangi bir kaplama, kaynakları geçersiz kılabilir. -
odm
. ODM bölümündeki herhangi bir kaplama, kaynakları geçersiz kılabilir. -
signature
. Hedef APK ile aynı imzayla imzalanan herhangi bir yer paylaşımı, kaynakları geçersiz kılabilir. -
actor
. Aktör APK'sıyla aynı imzayla imzalanan herhangi bir yer paylaşımı, kaynakları geçersiz kılabilir. Aktör, sistem yapılandırmasındaki adlandırılmış aktör etiketinde bildirildi. -
config_signature
. overlay-config apk ile aynı imzayla imzalanan herhangi bir kaplama, kaynakları geçersiz kılabilir. overlay-config, sistem yapılandırmasındaki overlay-config-signature etiketinde bildirilir.
Aşağıdaki kod res/values/overlayable.xml
dosyasındaki örnek bir <policy>
etiketini gösterir.
<overlayable name="ThemeResources">
<policy type="vendor" >
<item type="string" name="foo" />
</policy>
<policy type="product|signature" >
<item type="string" name="bar" />
<item type="string" name="baz" />
</policy>
</overlayable>
Birden çok politika belirtmek için ayırıcı karakterler olarak dikey çubukları (|) kullanın. Birden fazla politika belirtildiğinde, bir yer paylaşımının <policy>
etiketi içinde listelenen kaynakları geçersiz kılmak için yalnızca bir politikayı yerine getirmesi gerekir.
Kaplamaları yapılandırma
Android, Android sürüm sürümüne bağlı olarak katmanların değişebilirliğini, varsayılan durumunu ve önceliğini yapılandırmak için farklı mekanizmaları destekler.
Android 11 veya üstünü çalıştıran cihazlar, manifest nitelikleri yerine
OverlayConfig
dosyasını (config.xml
) kullanabilir. Kaplama dosyası kullanmak kaplamalar için önerilen yöntemdir.Tüm cihazlar, statik RRO'ları yapılandırmak için bildirim niteliklerini (
android:isStatic
veandroid:priority
) kullanabilir.
OverlayConfig'i kullanma
Android 11 veya sonraki sürümlerde, katmanların değiştirilebilirliğini, varsayılan durumunu ve önceliğini yapılandırmak için OverlayConfig
kullanabilirsiniz. Bir kaplamayı yapılandırmak için, partition/overlay/config/config.xml
konumunda bulunan dosyayı oluşturun veya değiştirin; burada partition
yapılandırılacak kaplamanın bölümüdür. Yapılandırılabilmesi için bir kaplamanın, kaplamanın yapılandırıldığı bölümün overlay/
dizininde bulunması gerekir. Aşağıdaki kod örnek bir product/overlay/config/config.xml
gösterir.
<config>
<merge path="OEM-common-rros-config.xml" />
<overlay package="com.oem.overlay.device" mutable="false" enabled="true" />
<overlay package="com.oem.green.theme" enabled="true" />
</config>"
<overlay>
etiketi, hangi yer paylaşımı paketinin yapılandırıldığını belirten bir package
niteliği gerektirir. İsteğe bağlı enabled
özelliği, kaplamanın varsayılan olarak etkin olup olmadığını kontrol eder (varsayılan, false
). İsteğe bağlı mutable
özelliği, kaplamanın değiştirilebilir olup olmadığını ve etkin durumunun çalışma zamanında programlı olarak değiştirilip değiştirilemeyeceğini kontrol eder (varsayılan true
). Bir yapılandırma dosyasında listelenmeyen katmanlar değiştirilebilir ve varsayılan olarak devre dışıdır.
Yer paylaşımı önceliği
Birden fazla katman aynı kaynakları geçersiz kıldığında katmanların sırası önemlidir. Bir yer paylaşımı, kendi konfigürasyonundan önce gelen konfigürasyonlara sahip yer paylaşımlarından daha büyük önceliğe sahiptir. Farklı bölümlerdeki katmanların öncelik sırası (en küçükten en büyüğe doğru) aşağıdaki gibidir.
-
system
-
vendor
-
odm
-
oem
-
product
-
system_ext
Dosyaları birleştirme
<merge>
etiketlerinin kullanılması, diğer yapılandırma dosyalarının belirtilen konumda yapılandırma dosyasıyla birleştirilmesine olanak tanır. Etiketin path
niteliği, yer paylaşımı yapılandırma dosyalarını içeren dizine göre birleştirilecek dosyanın yolunu temsil eder.
Bildirim niteliklerini kullanma (statik RRO'lar)
Android 10 veya daha düşük sürümlerde yer paylaşımının değişmezliği ve öncelik, aşağıdaki manifest nitelikleri kullanılarak yapılandırılır.
android:isStatic
. Bu boole özelliğinin değeritrue
olarak ayarlandığında, kaplama varsayılan olarak etkinleştirilir ve değiştirilemez; bu da kaplamanın devre dışı bırakılmasını engeller.android:priority
. Bu sayısal özelliğin değeri (yalnızca statik kaplamaları etkiler), birden fazla statik kaplama aynı kaynak değerini hedeflediğinde kaplamanın önceliğini yapılandırır. Daha yüksek bir sayı, daha yüksek bir önceliği gösterir.
Aşağıdaki kod bir AndroidManifest.xml
örneğini gösterir.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.overlay">
<application android:hasCode="false" />
<overlay android:targetPackage="com.example.target"
android:isStatic="true"
android:priority="5"/>
</manifest>
Android 11'deki değişiklikler
Android 11 veya sonraki sürümlerde, bir yapılandırma dosyası partition/overlay/config/config.xml
konumunda bulunuyorsa kaplamalar bu dosya kullanılarak yapılandırılır ve android:isStatic
ve android:priority
bölümde bulunan kaplamalar üzerinde bir etkisi yoktur. Herhangi bir bölümde bir yer paylaşımı yapılandırma dosyasının tanımlanması, yer paylaşımı bölümünün önceliğini zorunlu kılar.
Ayrıca Android 11 veya üzeri, paket kurulumu sırasında okunan kaynakların değerlerini etkilemek için statik katmanlar kullanma özelliğini ortadan kaldırır. Bileşenin etkin durumunu yapılandıran boolean'ların değerini değiştirmek amacıyla statik katmanların kullanılması şeklindeki yaygın kullanım durumu için <component-override>
SystemConfig
etiketini kullanın (Android 11'de yeni).
Kaplamalarda hata ayıklama
Kaplamaları manuel olarak etkinleştirmek, devre dışı bırakmak ve boşaltmak için aşağıdaki kaplama yöneticisi kabuk komutunu kullanın.
adb shell cmd overlay
OverlayManagerService
hedef paketteki kaynak kimliklerini yer paylaşımı paketindeki kaynak kimlikleriyle eşleştirmek için idmap2
kullanır. Oluşturulan kimlik eşlemeleri /data/resource-cache/
konumunda saklanır. Kaplamanız düzgün çalışmıyorsa, kaplamanız için karşılık gelen idmap
dosyasını /data/resource-cache/
içinde bulun ve ardından aşağıdaki komutu çalıştırın.
adb shell idmap2 dump --idmap-path [file]
Bu komut, aşağıda gösterildiği gibi kaynakların eşlemesini yazdırır.
[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType