Çalışma Zamanı Kaynak Bindirmeleri (RRO'lar)

Ç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. RROs (ancak, varsayılan olarak devre dışıdır statik RROs 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 içeriyorsa bir paket, bir RRO paket kabul edilir <overlay> alt öğesi olarak etiketi <manifest> etiketi.

  • Gerekli değeri android:targetPackage nitelik belirttiği paketin adı RRO bindirme niyetinde.

  • Opsiyonel değeri android:targetName nitelik belirttiği RRO bindirmek niyetinde hedef paketinin kaynakların overlayable alt kümesi adı. Hedef, kaplanabilir bir kaynak kümesi tanımlamıyorsa, bu öznitelik mevcut olmamalıdır.

Aşağıdaki kod, katlamalı bir örnek AndroidManifest.xml .

<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. Buna ek olarak, android:hasCode öznitelik <application > manifest'te etiketi şekilde ayarlanması gerekir false .

Kaynak haritasını tanımlama

Android 11 veya daha yer paylaşımı kaynakları harita tanımlamak için tavsiye edilen mekanizma bir dosya oluşturmaktır res/xml , bindirme paketinin dizinde Kaplanmış olmalıdır hedef kaynaklarının ve bunların yedek koşulları sınar ardından değerini ayarlayın android:resourcesMap öznitelik <overlay> kaynak eşleme dosyasına bir referansa apaçık etiketi.

Aşağıdaki kod gösterileri örnek res/xml/overlays.xml dosyası.

<?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şturmak

Android 11 veya daha destekleri için Soong yapı kural bindirmeleri olduğu önler Android Varlık Packaging Araç 2 aynı değerde (ile kaynakların tekilleştirme yapılandırmaları teşebbüs den (AAPT2) --no-resource-deduping ) ve (varsayılan yapılandırmaları olmadan kaynak kaldırmasını --no-resource-removal ). Aşağıdaki kod örneği gösterir Android.bp dosyasını.

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. En uygun konfigürasyonu olan yapılandırma belirlemek için, hedef kaynak yapılandırmaları kümesi haline bindirme kaynak yapılandırmaları setini birleştirmek ve daha sonra (bkz, detaylar için düzenli bir kaynak çözünürlüğü akışını takip Nasıl Android'in en iyi eşleşme kaynak bulur ).

Bir bindirme için bir değer tanımlar, örneğin, drawable-en yapılandırma ve hedef için bir değer tanımlar drawable-en-port , drawable-en-port hedef görünüm değeri bu nedenle daha iyi bir uyumunun drawable-en-port olduğu çalışma zamanında seçilir. Tüm kaplamak için drawable-en yapılandırmalarında, bindirme her biri için bir değeri vermek gerekir drawable-en yapılandırma hedef oluşturmaktadı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ı 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 daha düşük olarak, bindirmeleri ve hedef paketleri kullandıkları kendi kaynaklarını referans çalıştıklarında çarpışmalar ve beklenmedik davranışlara neden olabilir aynı kaynak kimliği alanını paylaşan @type/name sözdizimi.

Bindirmeleri etkinleştirme/devre dışı bırakma

Kullanım OverlayManager etkinleştirmek ve devre dışı bırakmak değişken bindirmeleri (kullanarak arayüz API almak için API Context#getSystemService(Context.OVERLAY_SERVICE) ). Bir bindirme sadece hedeflediği paket tarafından veya bir paket tarafından etkinleştirilebilir android.permission.CHANGE_OVERLAY_PACKAGES izni. Bir yer paylaşımı 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 daha yüksek ise, <overlayable> XML etiketi RROs yer paylaşımına izin verildiğini kaynakların kümesi gösterir. Aşağıdaki örnekte res/values/overlayable.xml dosya, string/foo ve integer/bar cihazın görünümünü theming için kullanılan kaynaklardır; bu kaynakları kaplamak için bir kaplamanın, kaplama 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 tanımlayabilirsiniz <overlayable> etiketleri, ama her etiket paketinin içinde benzersiz bir adı olmalıdır. Örneğin:

  • Tamam her ikisi için iki farklı paketler tanımlamak için <overlayable name="foo"> .

  • Tamam Tek bir APK iki olması için <overlayable name="foo"> blokları.

Aşağıdaki kod içinde bir bindirme örneğini göstermektedir AndroidManifest.xml dosyası.

<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>

Uygulamaya bir tanımlamaktadır zaman <overlayable> etiketi, söz konusu uygulamayı hedefleyen bindirmeleri:

  • Belirtilmelidir targetName .

  • İçinde listelenen kaynakları bindirmek Can <overlayable> etiketi.

  • Sadece bir hedefleyebilir <overlayable> adını.

Sen overlayable kaynaklarını ortaya çıkarır ama kullanmayan bir paket hedefleyen bir bindirme etkinleştiremiyorum android:targetName bir spesifik hedef <overlayable> etiketi.

kısıtlama politikaları

Kullan <policy> overlayable kaynaklar üzerindeki kısıtlamaları uygulamak için etiketi. type bir bindirme yerine getirmesi gereken politikaları nitelik belirtir dahil kaynakların geçersiz kılmak için. 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 gösterileri örnek <policy> etiketi res/values/overlayable.xml dosyası.

<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 politikaları belirtildiğinde, bir bindirme içinde listelenen kaynakları geçersiz kılmak için tek politikasına uygun olması gerekir <policy> etiketinin.

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 üstünü çalıştıran cihazlar bir kullanabilir OverlayConfig dosyası ( config.xml yerine tezahür niteliklerin). Bir bindirme dosyası kullanmak, bindirmeler için önerilen yöntemdir.

  • (Tüm cihazlar tezahür özelliklerini kullanabilirsiniz android:isStatic ve android:priority yapılandırmak statik RROs kadar).

OverlayConfig'i kullanma

Android 11 veya daha, sen kullanabilirsiniz OverlayConfig bindirmeleri mutability, varsayılan durumunu ve önceliğini yapılandırmak için. Bir bindirme yapılandırmak için bulunan dosya oluşturmak veya değiştirmek partition/overlay/config/config.xml , nereye partition yapılandırılacak bindirmenin bölümdür. Yapılandırılmalıdır için bir bindirme bulunması gerekir overlay/ bindirme yapılandırıldığı bölümünün dizininde. Aşağıdaki kod, bir örnek product/overlay/config/config.xml .

<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 gerektirir package yapılandırılmış olan hangi bindirme paketi gösterir niteliğini. Opsiyonel enabled bindirme (varsayılan varsayılan olarak etkin olup olmadığını özellik denetimleri false ). İsteğe bağlı mutable bindirme değişken ve onun etkin devlet zamanında program tarafından değiştirilemez sahip olup olmadığını özellik denetimleri (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, kendi konfigürasyonundan önce gelen konfigürasyonlara sahip 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

Kullanımı <merge> diğer yapılandırma dosyaları yapılandırma dosyasına belirtilen pozisyonda birleştirilecek için etiket verir. path etiketinin nitelik dosyasının yolunu yapılandırma dosyaları bindirme içeren dizinine göre birleştirme 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 özelliğin değeri olarak ayarlandığında true , bindirme varsayılan olarak etkindir ve devre dışı bırakıldıktan bindirmeyi engelleyen sabittir.

  • 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 örneğini göstermektedir AndroidManifest.xml .

<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 daha yüksek bir yapılandırma dosyası bulunuyorsa partition/overlay/config/config.xml , bindirmeleri bu dosyayı kullanarak yapılandırılır android:isStatic ve android:priority bölümünde bulunan bindirmeleri üzerinde etkisi yoktur. Herhangi bir bölümde bir bindirme yapılandırma dosyası tanımlamak, bindirme bölümü önceliğini zorlar.

Ayrıca, Android 11 veya üzeri, paket kurulumu sırasında okunan kaynakların değerlerini etkilemek için statik bindirmeleri kullanma özelliğini kaldırır. Yapılandırmak parça devlet etkin olduğunu boole değerini değiştirmek için statik bindirmeleri kullanmanın genel kullanım durumunda için kullanmak <component-override> SystemConfig (Android 11'de yeni) etiketi.

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 kullandığı idmap2 bindirme paketinde kaynak kimlikleri hedef paketinde kaynak kimlikleri haritaya. Oluşturulan kimlik dönüşümler saklanır /data/resource-cache/ . Paylaşımınızın düzgün çalışmıyorsa, ilgili bulmak idmap içinde Bindirmenizi için dosya /data/resource-cache/ 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