Çalışma zamanında kaynak eşlemesi (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, davranışını bir kaynağın değerine göre değiştirebilir. Farklı bir bölüme yüklenen bir RRO, kaynak değerini derleme zamanında sabit kodlamak yerine uygulamanın 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 özelliğini etkinleştirmek/devre dışı bırakmak için etkinleştirme/devre dışı bırakma durumunu programatik olarak ayarlayabilirsiniz. RRO'lar varsayılan olarak devre dışıdır (ancak statik RRO'lar varsayılan olarak etkindir).
Yer paylaşımı kaynakları
Yer paylaşımları, yer paylaşımı 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şımı kaynağının değeri döndürülür.
Manifest dosyasını ayarlama
<manifest>
etiketinin alt öğesi olarak <overlay>
etiketi içeren paketler RRO paketi olarak kabul edilir.
Zorunlu
android:targetPackage
özelliğinin değeri, RRO'nun yer paylaşımı yapmak istediği paketin adını belirtir.İsteğe bağlı
android:targetName
özelliğinin değeri, RRO'nun yer paylaşımı yapmak istediği hedef paketin yer paylaşımına uygun kaynak alt kümesinin adını belirtir. Hedef, üzerine yazılabilir bir kaynak grubu tanımlamıyorsa bu özellik mevcut olmamalıdır.
Aşağıdaki kodda örnek bir yer paylaşımı AndroidManifest.xml
gösterilmektedir.
<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ı kod üzerine yerleştirilemediğinden DEX dosyaları içeremez. Ayrıca, manifest dosyasında <application
> etiketinin android:hasCode
özelliği false
olarak ayarlanmalıdır.
Kaynak haritasını tanımlama
Android 11 veya sonraki sürümlerde yer paylaşımı kaynak 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 yerine kullanılacak değerleri numaralandırmak, ardından <overlay>
manifest etiketinin android:resourcesMap
özelliğinin değerini kaynak eşleme dosyasına referans olacak şekilde ayarlamaktır.
Aşağıdaki kodda bir res/xml/overlays.xml
dosyası örneği gösterilmektedir.
<?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 kodda örnek bir yer paylaşımı manifesti gösterilmektedir.
<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 sonraki sürümler, 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ı olmayan kaynakları (--no-resource-removal
) kaldırmasını önleyen bir Soong derleme kuralı destekler. Aşağıdaki kodda örnek bir Android.bp
dosyası gösterilmektedir.
runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
Kaynakları çözme
Bir hedef kaynak veya yer paylaşımı kaynağında, sorgulanan kaynak için birden fazla yapılandırma tanımlanmışsa kaynak çalışma zamanı, cihaz yapılandırmasıyla en iyi eşleşen yapılandırma değerini döndürür. En iyi eşleşen yapılandırma hangisiyse belirlemek için yer paylaşımı kaynak yapılandırmaları grubunu hedef kaynak yapılandırmaları grubuyla birleştirin ve ardından normal kaynak çözümü akışını uygulayın (ayrıntılar için Android en iyi eşleşen kaynağı nasıl bulur? başlıklı makaleyi inceleyin).
Örneğin, bir yer paylaşımı drawable-en
yapılandırması için bir değer tanımlar ve hedef drawable-en-port
için bir değer tanımlarsa drawable-en-port
daha iyi bir eşleşmeye sahiptir. Bu nedenle, çalışma zamanında hedef yapılandırma drawable-en-port
değerinin değeri seçilir. Tüm drawable-en
yapılandırmalarını yer paylaşımına eklemek için yer paylaşımının, hedefin tanımladığı her drawable-en
yapılandırması için bir değer tanımlaması gerekir.
Yer paylaşımları, Android sürümleri arasında farklı davranışlarla kendi kaynaklarına referans verebilir.
Android 11 veya sonraki sürümlerde her yer paylaşımının, hedef kaynak kimliği alanıyla veya diğer yer paylaşımı kaynak kimliği alanlarıyla çakışmayan 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 yer paylaşımları ve hedef paketler aynı kaynak kimliği alanını paylaşır. Bu durum,
@type/name
söz dizimini kullanarak kendi kaynaklarına referans vermeye çalıştıklarında çakışmalara ve beklenmedik davranışlara neden olabilir.
Yer paylaşımlarını etkinleştirme/devre dışı bırakma
Yer paylaşımları manuel olarak ve programatik olarak etkinleştirilebilir/devre dışı bırakılabilir.
Yer paylaşımlarını manuel olarak devre dışı bırakma veya etkinleştirme
RRO'yu manuel olarak etkinleştirmek ve doğrulamak için:
adb shell cmd overlay enable --user current com.example.carrro
adb shell cmd overlay list --user current | grep -i com.example com.example.carrro
Bu işlem, SystemUI'nin sahibi olan sistem kullanıcısı (userId = 0
) için RRO'yu etkinleştirir.
Bu talimat, ön plan kullanıcısı (userId = 10
) tarafından başlatılan uygulamaları etkilemez. Ön plan kullanıcısı için RRO'yu etkinleştirmek üzere -–user 10
parametresini kullanın:
adb shell cmd overlay enable --user 10 com.example.carrro
Yer paylaşımlarını programatik olarak etkinleştirme veya devre dışı bırakma
Değiştirilebilir yer paylaşımlarını etkinleştirmek ve devre dışı bırakmak için OverlayManager
API'yi 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 yer paylaşımı etkinleştirildiğinde veya devre dışı bırakıldığında, yapılandırma değişikliği etkinlikleri 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 yer paylaşımına izin verilen bir kaynak grubunu gösterir. Aşağıdaki res/values/overlayable.xml
dosyası örneğinde string/foo
ve integer/bar
, cihazın görünümünü temalandırmak için kullanılan kaynaklardır. Bu kaynakların üzerine binmesi için yer paylaşımının, yer paylaşımına uygun kaynakları isme 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
<overlayable name="foo">
değerini tanımlaması sorun oluşturmaz.Tek bir APK'da iki
<overlayable name="foo">
bloğu bulunması kabul edilemez.
Aşağıdaki kodda, AndroidManifest.xml
dosyasında yer alan bir yer paylaşımı örneği gösterilmektedir.
<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 <overlayable>
etiketi tanımladığında, bu uygulamayı hedefleyen yer paylaşımları:
targetName
belirtilmelidir.Yalnızca
<overlayable>
etiketinde listelenen kaynakları yer paylaşımı olarak kullanabilir.Yalnızca bir
<overlayable>
adını hedefleyebilir.
Yerleşik kaynaklar gösteren ancak belirli bir <overlayable>
etiketini hedeflemek için android:targetName
kullanmayan bir paketi hedefleyen bir yer paylaşımını etkinleştiremezsiniz.
Politikaları kısıtlama
Yerleştirilebilir kaynaklarda kısıtlamaları zorunlu kılmak için <policy>
etiketini kullanın. type
özelliği, dahil edilen kaynakları geçersiz kılmak için bir yer paylaşımının hangi politikaları karşılaması gerektiğini belirtir. Desteklenen türler şunlardır.
public
. Herhangi bir yer paylaşımı kaynağı geçersiz kılabilir.system
. Sistem bölümündeki tüm yer paylaşımları kaynakları geçersiz kılabilir.vendor
. Tedarikçi firma bölümündeki tüm yer paylaşımları kaynakları geçersiz kılabilir.product
. Ürün bölümündeki tüm yer paylaşımları kaynakları geçersiz kılabilir.oem
. OEM bölümündeki tüm yer paylaşımları kaynakları geçersiz kılabilir.odm
. odm bölümündeki herhangi bir yer paylaşımı, kaynakları geçersiz kılabilir.signature
. Hedef APK ile aynı imzayla imzalanan tüm yer paylaşımları kaynakları geçersiz kılabilir.actor
. Aktör APK'sıyla aynı imzayla imzalanan tüm yer paylaşımları kaynakları geçersiz kılabilir. Oyuncu, sistem yapılandırmasında named-actor etiketinde belirtilir.config_signature
. Overlay-config APK'sıyla aynı imzayla imzalanan tüm yer paylaşımları kaynakları geçersiz kılabilir. Yer paylaşımı yapılandırması, sistem yapılandırmasında yer paylaşımı yapılandırması imzası etiketinde tanımlanır.
Aşağıdaki kodda, res/values/overlayable.xml
dosyasında bir örnek <policy>
etiketi gösterilmektedir.
<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 fazla politika belirtmek için ayırıcı karakter olarak dikey çubuklar (|) kullanın.
Birden fazla politika belirtildiğinde, <policy>
etiketinde listelenen kaynakları geçersiz kılmak için yer paylaşımının yalnızca bir politikayı karşılaması gerekir.
Yer paylaşımlarını yapılandırma
Android, Android 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, manifest özellikleri yerine
OverlayConfig
dosyası (config.xml
) kullanabilir. Yer paylaşımları için önerilen yöntem, yer paylaşımı dosyası kullanmaktır.Tüm cihazlar, statik RRO'ları yapılandırmak için manifest özelliklerini (
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
öğesini kullanabilirsiniz. Yer paylaşımını yapılandırmak için partition/overlay/config/config.xml
adresinde bulunan dosyayı oluşturun veya değiştirin. Burada partition
, yer paylaşımının yapılandırılacak bölümüdür. Yapılandırılmak için yer paylaşımının, yer paylaşımının yapılandırıldığı bölümün overlay/
dizininde bulunması gerekir. Aşağıdaki kodda bir product/overlay/config/config.xml
örneği gösterilmektedir.
<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ılacağını belirten bir package
özelliği gerektirir. İsteğe bağlı enabled
özelliği, yer paylaşımının varsayılan olarak etkin olup olmadığını kontrol eder (varsayılan değer false
). İsteğe bağlı mutable
özelliği, yer paylaşımının değiştirilip değiştirilemeyeceğini ve etkin durumunun çalışma zamanında programatik olarak değiştirilip değiştirilemeyeceğini kontrol eder (varsayılan değer true
). Yapılandırma dosyasında listelenmeyen yer paylaşımları değiştirilebilir ve varsayılan olarak devre dışıdır.
Yer paylaşımı önceliği
Birden fazla yer paylaşımı aynı kaynakları geçersiz kıldığında yer paylaşımlarının sırası önemlidir. Bir yer paylaşımının önceliği, kendi yapılandırmasından önce gelen yapılandırmalara sahip yer paylaşımlarından daha yüksektir. Farklı bölümlerdeki yer paylaşımlarının öncelik sırası (en düşükten en yükseğe doğru) aşağıdaki gibidir.
system
vendor
odm
oem
product
system_ext
Dosyaları birleştirme
<merge>
etiketleri kullanmak, diğer yapılandırma dosyalarının yapılandırma dosyasında belirtilen konumda birleştirilmesine olanak tanır. Etiketin path
özelliği, yer paylaşımı yapılandırma dosyalarını içeren dizine göre birleştirilecek dosyanın yolunu temsil eder.
Manifest özelliklerini/statik RRO'ları kullanma
Android 10 veya önceki sürümlerde yer paylaşımının değişmezliği ve önceliği aşağıdaki manifest özellikleri kullanılarak yapılandırılır.
android:isStatic
. Bu boole özelliğinin değeritrue
olarak ayarlandığında yer paylaşımı varsayılan olarak etkinleştirilir ve değiştirilemez hale gelir. Bu da yer paylaşımının devre dışı bırakılmasını engeller.android:priority
. Bu sayısal özelliğin değeri (yalnızca statik yer paylaşımlarını etkiler), birden fazla statik yer paylaşımı aynı kaynak değerini hedeflediğinde yer paylaşımının önceliğini yapılandırır. Daha yüksek bir sayı, daha yüksek öncelik anlamına gelir.
Aşağıdaki kodda bir örnek AndroidManifest.xml
gösterilmektedir.
<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ı varsa yer paylaşımları bu dosya kullanılarak yapılandırılır ve android:isStatic
ile android:priority
, bölümdeki yer paylaşımlarını etkilemez. Herhangi bir bölümde yer paylaşımı yapılandırma dosyası tanımlamak, yer paylaşımı bölümünün önceliğini zorunlu kılar.
Ayrıca Android 11 veya sonraki sürümlerde, paket yükleme sırasında okunan kaynakların değerlerini etkilemek için statik yer paylaşımları kullanma özelliği kaldırılmıştır. Bileşen etkin durumunu yapılandıran doğru/yanlış değerlerinin değerini değiştirmek için statik yer paylaşımlarını kullanmanın yaygın kullanım alanı için <component-override>
SystemConfig
etiketini kullanın (Android 11'de yeni).
Hata ayıklama yer paylaşımları
Yer paylaşımlarını manuel olarak etkinleştirmek, devre dışı bırakmak ve dökmek için aşağıdaki yer paylaşımı yöneticisi kabuk komutunu kullanın.
adb shell cmd overlay
enable
işlevi kullanıcı belirtmeden kullanıldığında geçerli kullanıcı, yani sistem kullanıcı arayüzünün sahibi olan sistem kullanıcısı (userId = 0
) etkilenir. Bu durum, uygulamaların sahibi olan ön plan kullanıcısını (userId = 10
) etkilemez. Ön plan kullanıcısı için RRO'yu etkinleştirmek üzere –-user 10
parametresini kullanın:
adb shell cmd overlay enable --user 10 com.example.carrro
OverlayManagerService
, hedef paketteki kaynak kimliklerini yer paylaşımı paketindeki kaynak kimlikleriyle eşlemek için idmap2
'u kullanır. Oluşturulan kimlik eşlemeleri /data/resource-cache/
içinde depolanır. Yer paylaşımınız düzgün çalışmıyorsa /data/resource-cache/
'te yer paylaşımınıza karşılık gelen idmap
dosyasını bulun ve aşağıdaki komutu çalıştırın.
adb shell idmap2 dump --idmap-path [file]
Bu komut, kaynakların eşlemesini aşağıda gösterildiği gibi 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