Çalışma zamanı kaynak yerleşimi (RRO), çalışma zamanında hedef paketin kaynak değerlerini değiştiren bir pakettir. Örneğin, sistem görüntüsüne yüklenen bir uygulama, davranışını bir kaynağın değerine göre değiştirebilir. Kaynak değerini derleme zamanı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 programlı olarak ayarlayabilirsiniz. RRO'lar varsayılan olarak devre dışıdır (ancak, statik RRO'lar varsayılan olarak etkindir).
Kaynakları bindirme
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 yer paylaşımlı kaynağın değeri döndürülür.
Manifest'i ayarlama
Bir paket, <manifest>
etiketinin alt öğesi olarak bir <overlay>
etiketi içeriyorsa, 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 bindirilebilir kaynak alt kümesinin adını belirtir. Hedef, üst üste bindirilebilir bir kaynak kümesi tanımlamıyorsa, bu öznitelik mevcut olmamalıdır.
Aşağıdaki kod, örnek bir yer paylaşımı AndroidManifest.xml
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>
Bindirmeler kodu kaplayamaz, dolayısıyla DEX dosyalarına sahip olamazlar. Ayrıca, bildirimdeki <application
> etiketinin android:hasCode
özniteliği false
olarak ayarlanmalıdır.
Kaynak haritasını tanımlama
Android 11 veya sonraki sürümlerde, bindirme kaynakları haritasını tanımlamak için önerilen mekanizma, bindirme paketinin res/xml
dizininde bir dosya oluşturmak, üst üste bindirilmesi gereken hedef kaynakları ve bunların değiştirme değerlerini numaralandırmak, ardından değerini ayarlamaktır. <overlay>
manifest etiketinin android:resourcesMap
özniteliği, kaynak eşleme dosyasına bir başvuruya.
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 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şturmak
Android 11 veya sonraki sürümleri, Android Asset Packaging Tool 2'nin (AAPT2) aynı değere sahip kaynakların yapılandırmalarını tekilleştirmeye çalışmasını ( --no-resource-deduping
) ve varsayılan yapılandırmalar olmadan kaynakları kaldırmasını ( --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 yapılandırmanın en iyi eşleşen yapılandırma olduğunu belirlemek için, kaplama 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 en uygun kaynağı nasıl bulur bölümüne bakın).
Örneğin, bir bindirme, drawable-en
yapılandırması için bir değer tanımlarsa ve hedef, drawable-en-port
için bir değer tanımlarsa, drawable-en-port
daha iyi bir eşleşmeye sahiptir, dolayısıyla, drawable-en-port
hedef yapılandırmasının değeri şöyle olur: çalışma zamanında seçilir. Tüm drawable-en
konfigürasyonları kaplamak için kaplama, hedefin tanımladığı her drawable-en
konfigürasyon için bir değer tanımlamalıdır.
Yer paylaşımları, Android sürümleri arasında farklı davranışlarla kendi kaynaklarına başvurabilir.
Android 11 veya sonraki sürümlerde, her kaplamanın hedef kaynak kimliği alanıyla veya diğer kaplama kaynak kimliği alanlarıyla çakışmayan 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, kaplamalar 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 çakışmalara ve beklenmeyen davranışlara neden olabilir.
Bindirmeleri etkinleştirme/devre dışı bırakma
Değiştirilebilir 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 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.
Üst üste bindirilebilir kaynakları kısıtlama
Android 10 veya sonraki sürümlerde, <overlayable>
XML etiketi, RRO'ların bindirmesine izin verilen bir dizi kaynağı ortaya çıkarır. Aşağıdaki örnekte res/values/overlayable.xml
dosyasında, string/foo
ve integer/bar
, aygıtın görünümünü oluşturmak için kullanılan kaynaklardır; bu kaynakları kaplamak için, kaplamanın açık bir şekilde kaplama kaynakların koleksiyonunu ada göre 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:
Her ikisinin de
<overlayable name="foo">
tanımlaması için iki farklı paket için tamam.Tek bir APK'nın 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>
etiketinde listelenen kaynakları kaplayabilir.Yalnızca bir
<overlayable>
adı hedefleyebilir.
Bindirilebilir kaynakları ortaya çıkaran ancak belirli bir <overlayable>
etiketini hedeflemek için android:targetName
kullanmayan bir paketi hedefleyen bir kaplamayı etkinleştiremezsiniz.
kısıtlama politikaları
Üst üste bindirilebilir kaynaklar üzerindeki kısıtlamaları uygulamak için <policy>
etiketini kullanın. type
özelliği, dahil edilen kaynakları geçersiz kılmak için bir kaplamanın hangi ilkeleri 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 kaplama, kaynakları geçersiz kılabilir. -
vendor
. Satıcı bölümündeki herhangi bir kaplama, kaynakları geçersiz kılabilir. -
product
. Ürün bölümündeki herhangi bir kaplama, kaynakları geçersiz kılabilir. -
signature
Hedef APK ile aynı imzayla imzalanmış herhangi bir bindirme, kaynakları geçersiz kılabilir.
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 yer paylaşımlarının değişebilirliğini, varsayılan durumunu ve önceliğini yapılandırmak için farklı mekanizmaları destekler.
Android 11 veya sonraki sürümleri çalıştıran cihazlar, bildirim öznitelikleri yerine bir
OverlayConfig
dosyası (config.xml
) kullanabilir. Bir bindirme dosyası kullanmak, bindirmeler için önerilen yöntemdir.Tüm cihazlar, statik RRO'ları yapılandırmak için bildirim özniteliklerini (
android:isStatic
veandroid:priority
) kullanabilir.
OverlayConfig'i kullanma
Android 11 veya sonraki sürümlerde, yer paylaşımlarının değişebilirliğ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
, yapılandırılacak bindirmenin bölümüdür. Yapılandırılması için, bindirmenin yapılandırıldığı bölümün overlay/
dizininde bir kaplama bulunmalıdır. Aşağıdaki kod, bir product/overlay/config/config.xml
örneğini 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 bindirme paketinin yapılandırıldığını gösteren bir package
özniteliği gerektirir. İsteğe bağlı enabled
özniteliği, kaplamanın varsayılan olarak etkinleştirilip etkinleştirilmediğini denetler (varsayılan olarak false
). İsteğe bağlı mutable
özniteliği, kaplamanın değişebilir olup olmadığını denetler ve etkin durumunun çalışma zamanında programlı olarak değiştirilmesini sağlayabilir (varsayılan true
). Bir yapılandırma dosyasında listelenmeyen kaplamalar değiştirilebilir ve varsayılan olarak devre dışıdır.
Yer paylaşımı önceliği
Birden çok kaplama aynı kaynakları geçersiz kıldığında, kaplamaların sırası önemlidir. Bir bindirme, konfigürasyonları kendi konfigürasyonundan önce gelen bindirmelerden daha büyük önceliğe sahiptir. Farklı bölümlerdeki bindirmelerin öncelik sırası (en küçükten en büyüğe) aşağıdaki gibidir.
-
system
-
vendor
-
oem
-
odm
-
product
-
system_ext
Dosyaları birleştirme
<merge>
etiketlerinin kullanılması, diğer konfigürasyon dosyalarının konfigürasyon dosyasında belirtilen konumda birleştirilmesine izin verir. Etiketin path
özelliği, bindirme 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 ö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 özelliğ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ı önler.android:priority
. Bu sayısal özniteliğin değeri (yalnızca statik kaplamaları etkiler), birden çok 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 örnek AndroidManifest.xml
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
içinde bir yapılandırma dosyası bulunuyorsa, bindirmeler bu dosya kullanılarak yapılandırılır ve android:isStatic
ve android:priority
, bölümde bulunan bindirmeler üzerinde bir etkiye sahip değildir. Herhangi bir bölümde bir bindirme yapılandırma dosyası tanımlamak, bindirme bölümü önceliğini zorlar.
Ek olarak, Android 11 veya sonraki sürümler, paket yüklemesi sırasında okunan kaynakların değerlerini etkilemek için statik bindirmeleri kullanma özelliğini kaldırır. Bileşen etkin durumunu yapılandıran booleanları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).
Bindirmelerde 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/
içinde saklanır. Bindirmeniz düzgün çalışmıyorsa, bindirmeniz için ilgili 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şlenmesini 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