Ç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, bir kaynağın değerine bağlı olarak davranışını değiştirebilir. Oluşturma zamanında kaynak değerini sabit kodlamak yerine, farklı bir bölüme yüklenen bir RRO, çalışma zamanında uygulamanın kaynaklarının değerlerini 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 programlı olarak ayarlayabilirsiniz. RRO'lar varsayılan olarak devre dışıdır (ancak, statik RRO'lar varsayılan olarak etkindir).
Yer paylaşımlı kaynaklar
Kaplamalar, kaplama paketinde tanımlanan kaynakları hedef pakette tanımlanan kaynaklarla eşleyerek çalışır. Bir uygulama, hedef paketteki bir kaynağın değerini çözmeye çalıştığında, bunun yerine hedef kaynağın eşlendiği kaplama kaynağının değeri döndürülür.
bildirimi ayarlama
Bir paket, <manifest>
etiketinin alt öğesi olarak bir <overlay>
etiketi içeriyorsa, bir RRO paketi olarak kabul edilir.
Gerekli
android:targetPackage
özniteliğ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 yer paylaşımlı kaynak altkümesinin adını belirtir. Hedef, yer paylaşımlı bir kaynak kümesi tanımlamıyorsa, bu öznitelik mevcut olmamalıdır.
Aşağıdaki kod, örnek bir AndroidManifest.xml
kaplamasını 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"/>
</manifest>
Yer paylaşımları kodu kaplayamaz, dolayısıyla DEX dosyalarına sahip olamazlar. Ek olarak, bildirimdeki <application
> etiketinin android:hasCode
özniteliği false
olarak ayarlanmalıdır.
Kaynak haritasını tanımlama
Android 11 veya sonraki sürümlerde, kaplama kaynakları eşlemesini tanımlamak için önerilen mekanizma, kaplama paketinin res/xml
dizininde bir dosya oluşturmak, üzerine bindirilmesi gereken hedef kaynakları ve bunların değiştirme değerlerini numaralandırmak ve ardından değerini ayarlamaktır. <overlay>
manifest etiketinin android:resourcesMap
özniteliği, kaynak eşleme dosyasına bir referanstır.
Aşağıdaki kod, örnek bir res/xml/overlays.xml
dosyasını göstermektedir.
<?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 bindirme 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 üstü, Android Asset Packaging Tool 2'nin (AAPT2) aynı değere sahip ( --no-resource-deduping
) kaynakların yapılandırmalarını tekilleştirme girişiminde bulunmasını ve varsayılan yapılandırmalar olmadan ( --no-resource-removal
) kaynakları kaldırmasını engelleyen kaplamalar için bir Soong oluşturma 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ı çözme
Bir hedef kaynak veya kaplama kaynağı, sorgulanan kaynak için tanımlanmış birden çok yapılandırmaya sahipse, kaynakların çalışma zamanı, cihaz yapılandırmasının yapılandırmasıyla en iyi eşleşen yapılandırmanın değerini döndürür. Hangi konfigürasyonun en iyi eşleşen konfigürasyon olduğunu belirlemek için yer paylaşımlı kaynak konfigürasyonları setini hedef kaynak konfigürasyonları setiyle birleştirin ve ardından normal kaynak çözümleme akışını izleyin (ayrıntılar için Android en iyi eşleşen kaynağı nasıl bulur bölümüne bakın).
Örneğin, bir bindirme, drawable-en
-en-port için bir değer tanımlıyorsa ve hedef, drawable-en-port
için bir değer tanımlıyorsa, drawable-en-port
daha iyi bir eşleşmeye sahip olur, bu nedenle, drawable-en-port
hedef yapılandırmasının değeri şu şekilde olur: çalışma zamanında seçilir. Tüm drawable-en
konfigürasyonlarını kaplamak için, kaplamanın, hedefin tanımladığı her drawable-en
konfigürasyonu için bir değer tanımlaması gerekir.
Bindirmeler, Android sürümleri arasında farklı davranışlarla kendi kaynaklarına başvurabilir.
Android 11 veya sonraki sürümlerde, her yer paylaşımının, hedef kaynak kimliği alanı 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 başvuran kaplamalar beklendiği gibi çalışır.
Android 10 veya önceki sürümlerde, bindirmeler ve hedef paketler aynı kaynak kimliği alanını paylaşır; bu,
@type/name
sözdizimini kullanarak kendi kaynaklarına başvurmaya çalıştıklarında çarpışmalara ve beklenmeyen davranışlara neden olabilir.
Bindirmeleri 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). Kaplama, yalnızca hedeflediği paket tarafından veya android.permission.CHANGE_OVERLAY_PACKAGES
iznine sahip bir paket tarafından etkinleştirilebilir. Bir kaplama 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.
Yer paylaşımlı kaynakları kısıtlama
Android 10 veya sonraki sürümlerde, <overlayable>
XML etiketi, RRO'ların kaplamasına izin verilen bir dizi kaynağı gösterir. Aşağıdaki örnek res/values/overlayable.xml
dosyasında, string/foo
ve integer/bar
, aygıtın görünümünü temalandırmak için kullanılan kaynaklardır; bu kaynakları kaplamak için, bir kaplamanın yer paylaşımlı 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 çok <overlayable>
etiketi tanımlayabilir, ancak her etiketin paket içinde benzersiz bir adı olmalıdır. Örneğin, şu:
Her ikisinin de
<overlayable name="foo">
tanımlaması için iki farklı paket için uygundur.Tek bir APK'nin iki
<overlayable name="foo">
bloğuna sahip olması uygun değil.
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, o uygulamayı hedefleyen bindirmeler:
targetName
belirtilmelidir.Yalnızca
<overlayable>
etiketi içinde listelenen kaynakları kaplayabilir.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 yer paylaşımını etkinleştiremezsiniz.
Kısıtlama politikaları
Yer paylaşımlı kaynaklar üzerinde kısıtlamalar uygulamak için <policy>
etiketini kullanın. type
özniteliği, yer paylaşımının dahil edilen kaynakları geçersiz kılmak için hangi ilkeleri yerine getirmesi gerektiğini belirtir. Desteklenen türler aşağıdakileri içerir.
-
public
Herhangi bir yer paylaşımı, kaynağı geçersiz kılabilir. -
system
. Sistem bölümündeki herhangi bir yerleşim, kaynakları geçersiz kılabilir. -
vendor
Satıcı bölümündeki herhangi bir katman, kaynakları geçersiz kılabilir. -
product
Ürün bölümündeki herhangi bir yerleşim, kaynakları geçersiz kılabilir. -
oem
OEM bölümündeki herhangi bir yer paylaşımı, kaynakları geçersiz kılabilir. -
odm
odm bölümündeki herhangi bir katman, kaynakları geçersiz kılabilir. -
signature
Hedef APK ile aynı imzayla imzalanan herhangi bir kaplama, kaynakları geçersiz kılabilir. -
actor
Aktör APK'sı ile aynı imzayla imzalanmış herhangi bir bindirme, kaynakları geçersiz kılabilir. Aktör, sistem yapılandırmasında adlı aktör etiketinde bildirilir. -
config_signature
overlay-config apk ile aynı imzayla imzalanan herhangi bir kaplama, kaynakları geçersiz kılabilir. overlay-config, system config içindeki 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 ilke belirtmek için ayırıcı karakterler olarak dikey çubuklar (|) kullanın. Birden çok ilke belirtildiğinde, bir kaplamanın <policy>
etiketinde listelenen kaynakları geçersiz kılmak için yalnızca bir ilkeyi yerine getirmesi gerekir.
Bindirmeleri yapılandırma
Android, Android yayın sürümüne bağlı olarak bindirmelerin 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 öznitelikleri yerine bir
OverlayConfig
dosyası (config.xml
) kullanabilir. Bindirmeler için önerilen yöntem bir kaplama dosyası kullanmaktır.Tüm cihazlar, statik RRO'ları yapılandırmak için manifest özniteliklerini (
android:isStatic
veandroid:priority
) kullanabilir.
OverlayConfig'i Kullanma
Android 11 veya sonraki sürümlerde, bindirmelerin değişkenliğ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
bulunan dosyayı oluşturun veya değiştirin; burada partition
, kaplamanın yapılandırılacak bölümüdür. Yapılandırılması için, kaplamanın yapılandırıldığı bölümün overlay/
dizininde bir kaplama bulunmalıdır. Aşağıdaki kod, bir örnek 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 kaplama paketinin yapılandırıldığını gösteren bir package
özniteliği gerektirir. İsteğe bağlı enabled
özellik kaplamanın varsayılan olarak etkinleştirilip etkinleştirilmediğini denetler (varsayılan değer false
). İsteğe bağlı mutable
özniteliği, yer paylaşımının değişken olup olmadığını ve etkin durumunun çalışma zamanında programlı olarak değiştirilip değiştirilemeyeceğini kontrol eder (varsayılan değer true
). Yapılandırma dosyasında listelenmeyen bindirmeler değiştirilebilir ve varsayılan olarak devre dışıdır.
Bindirme önceliği
Birden çok kaplama aynı kaynakları geçersiz kıldığında, kaplamaların sırası önemlidir. Kaplama, kendi konfigürasyonundan önce gelen konfigürasyonlara sahip kaplamalardan daha yüksek önceliğe sahiptir. Farklı bölümlerdeki bindirmelerin ö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 izin verir. Etiketin path
niteliği, bindirme yapılandırma dosyalarını içeren dizine göre birleştirilecek dosyanın yolunu temsil eder.
Bildirim özelliklerini kullanma (statik RRO'lar)
Android 10 veya önceki sürümlerde yer paylaşımı değişmezliği ve öncelik, aşağıdaki bildirim öznitelikleri kullanılarak yapılandırılır.
android:isStatic
. Bu boole özniteliğinin değeritrue
olarak ayarlandığında, kaplama varsayılan olarak etkinleştirilir ve değişmezdir, bu da kaplamanın devre dışı bırakılmasını engeller.android:priority
. Bu sayısal özniteliğ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, 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, partition/overlay/config/config.xml
konumunda bir yapılandırma dosyası 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 kaplama yapılandırma dosyası tanımlamak, kaplama bölümü önceliğini zorlar.
Ek olarak, Android 11 veya üstü, paket kurulumu sırasında okunan kaynakların değerlerini etkilemek için statik yer paylaşımları kullanma özelliğini kaldırır. Bileşen etkin durumunu yapılandıran boolean'ların değerini değiştirmek üzere statik bindirmeleri kullanmanın yaygın kullanım durumu için, <component-override>
SystemConfig
etiketini kullanın (Android 11'de yeni).
Yer paylaşımlarında hata ayıklama
Yer paylaşımlarını manuel olarak etkinleştirmek, devre dışı bırakmak ve dökümü yapmak için aşağıdaki yer paylaşımı yöneticisi kabuk komutunu kullanın.
adb shell cmd overlay
OverlayManagerService
, hedef paketteki kaynak kimliklerini kaplama paketindeki kaynak kimlikleriyle eşlemek için idmap2
kullanır. Oluşturulan kimlik eşlemeleri /data/resource-cache/
içinde depolanır. Katmanınız düzgün çalışmıyorsa, /data/resource-cache/
içinde yer paylaşımınız için karşılık gelen idmap
dosyasını 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