Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Ubah nilai sumber daya aplikasi saat runtime

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Runtime resource overlay (RRO) adalah paket yang mengubah nilai sumber daya paket target saat runtime. Misalnya, aplikasi yang diinstal pada citra sistem mungkin mengubah perilakunya berdasarkan nilai sumber daya. Daripada meng-hardcoding nilai sumber daya pada waktu pembuatan, RRO yang diinstal pada partisi berbeda dapat mengubah nilai sumber daya aplikasi pada waktu proses.

RRO dapat diaktifkan atau dinonaktifkan. Anda dapat secara terprogram mengatur status aktifkan/nonaktifkan untuk mengaktifkan kemampuan RRO untuk mengubah nilai sumber daya. RRO dinonaktifkan secara default (namun, RRO statis diaktifkan secara default).

Melapisi sumber daya

Overlay bekerja dengan memetakan sumber daya yang ditentukan dalam paket overlay ke sumber daya yang ditentukan dalam paket target. Saat aplikasi mencoba menyelesaikan nilai sumber daya dalam paket target, nilai sumber daya overlay tempat sumber daya target dipetakan akan dikembalikan.

Menyiapkan manifes

Sebuah paket dianggap sebagai paket RRO jika berisi tag <overlay> sebagai turunan dari tag <manifest> .

  • Nilai atribut android:targetPackage yang diperlukan menentukan nama paket yang ingin dihamparkan oleh RRO.

  • Nilai atribut android:targetName opsional menentukan nama subkumpulan sumber daya yang dapat dihamparkan dari paket target yang ingin dihamparkan oleh RRO. Jika target tidak menentukan kumpulan sumber daya yang dapat dilapis, atribut ini tidak akan ada.

Kode berikut menampilkan contoh overlay 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>

Hamparan tidak dapat melapisi kode, sehingga tidak dapat memiliki file DEX. Selain itu, atribut android:hasCode dari tag <application > di manifes harus disetel ke false .

Menentukan peta sumber daya

Di Android 11 atau lebih tinggi, mekanisme yang direkomendasikan untuk menentukan peta resource overlay adalah membuat file di direktori res/xml paket overlay, menghitung resource target yang harus di-overlay dan nilai penggantinya, lalu menyetel nilai atribut android:resourcesMap dari tag manifes <overlay> ke referensi ke file pemetaan sumber daya.

Kode berikut menunjukkan contoh file res/xml/overlays.xml .

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

Kode berikut menampilkan contoh manifes overlay.

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

Membangun paket

Android 11 atau lebih tinggi mendukung aturan build Soong untuk overlay yang mencegah Android Asset Packaging Tool 2 (AAPT2) mencoba menghapus konfigurasi resource dengan nilai yang sama ( --no-resource-deduping ) dan menghapus resource tanpa konfigurasi default ( --no-resource-removal ). Kode berikut menampilkan contoh file Android.bp .

runtime_resource_overlay {
    name: "ExampleOverlay",
    sdk_version: "current",
}

Menyelesaikan sumber daya

Jika sumber daya target atau sumber daya overlay memiliki beberapa konfigurasi yang ditentukan untuk sumber daya yang dikueri, runtime sumber daya mengembalikan nilai konfigurasi yang paling sesuai dengan konfigurasi konfigurasi perangkat. Untuk menentukan konfigurasi mana yang merupakan konfigurasi yang paling cocok, gabungkan kumpulan konfigurasi sumber daya overlay ke dalam kumpulan konfigurasi sumber daya target, lalu ikuti alur resolusi sumber daya reguler (untuk mengetahui detailnya, lihat Cara Android menemukan sumber daya yang paling cocok ).

Misalnya, jika overlay menentukan nilai untuk konfigurasi drawable-en dan target menentukan nilai untuk drawable-en-port , drawable-en-port memiliki kecocokan yang lebih baik sehingga nilai konfigurasi target drawable-en-port adalah dipilih saat runtime. Untuk menghamparkan semua konfigurasi drawable-en , overlay harus menentukan nilai untuk setiap konfigurasi drawable-en yang ditentukan target.

Hamparan dapat mereferensikan sumber dayanya sendiri, dengan perilaku berbeda di antara rilis Android.

  • Di Android 11 atau lebih tinggi, setiap overlay memiliki ruang ID sumber daya yang dicadangkan sendiri yang tidak tumpang tindih dengan ruang ID sumber daya target atau ruang ID sumber daya overlay lainnya, sehingga hamparan yang mereferensikan sumber dayanya berfungsi seperti yang diharapkan.

  • Di Android 10 atau lebih rendah, overlay dan paket target berbagi ruang ID sumber daya yang sama, yang dapat menyebabkan tabrakan dan perilaku tak terduga saat mencoba mereferensikan sumber dayanya sendiri menggunakan sintaks @type/name .

Mengaktifkan/menonaktifkan overlay

Gunakan OverlayManager API untuk mengaktifkan dan menonaktifkan overlay yang dapat diubah (ambil antarmuka API menggunakan Context#getSystemService(Context.OVERLAY_SERVICE) ). Hamparan hanya dapat diaktifkan oleh paket yang ditargetkan atau oleh paket dengan izin android.permission.CHANGE_OVERLAY_PACKAGES . Saat overlay diaktifkan atau dinonaktifkan, peristiwa perubahan konfigurasi menyebar ke paket target dan meluncurkan kembali aktivitas target.

Membatasi sumber daya overlay

Di Android 10 atau lebih tinggi, tag XML <overlayable> menampilkan sekumpulan resource yang boleh di-overlay oleh RRO. Dalam contoh file res/values/overlayable.xml , string/foo dan integer/bar adalah sumber daya yang digunakan untuk memberi tema tampilan perangkat; untuk menghamparkan sumber daya ini, hamparan harus secara eksplisit menargetkan kumpulan sumber daya yang dapat dihamparkan berdasarkan nama.

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

APK dapat menentukan beberapa <overlayable> , tetapi setiap tag harus memiliki nama unik di dalam paket. Misalnya, ini adalah:

  • OK untuk dua paket berbeda untuk menentukan <overlayable name="foo"> .

  • Tidak apa-apa jika satu APK memiliki dua <overlayable name="foo"> .

Kode berikut menampilkan contoh overlay di file AndroidManifest.xml .

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

Saat aplikasi menentukan tag <overlayable> , overlay menargetkan aplikasi tersebut:

  • Harus menentukan targetName .

  • Hanya dapat melapisi sumber daya yang tercantum dalam tag <overlayable> .

  • Hanya dapat menargetkan satu nama <overlayable> .

Anda tidak dapat mengaktifkan overlay yang menargetkan paket yang menampilkan sumber daya overlay tetapi tidak menggunakan android:targetName untuk menargetkan tag <overlayable> tertentu.

Membatasi kebijakan

Gunakan tag <policy> untuk menerapkan batasan pada sumber daya yang dapat dilapis. Atribut type menentukan kebijakan mana yang harus dipenuhi overlay untuk mengganti sumber daya yang disertakan. Jenis yang didukung termasuk yang berikut ini.

  • public . Hamparan apa pun dapat menimpa sumber daya.
  • system . Hamparan apa pun pada partisi sistem dapat menimpa sumber daya.
  • vendor . Hamparan apa pun pada partisi vendor dapat menimpa sumber daya.
  • product . Hamparan apa pun pada partisi produk dapat menimpa sumber daya.
  • oem . Hamparan apa pun pada partisi oem dapat menimpa sumber daya.
  • odm . Hamparan apa pun pada partisi odm dapat menimpa sumber daya.
  • signature . Hamparan apa pun yang ditandatangani dengan tanda tangan yang sama dengan APK target dapat menggantikan sumber daya.
  • actor . Hamparan apa pun yang ditandatangani dengan tanda tangan yang sama dengan APK aktor dapat menggantikan sumber daya. Aktor dideklarasikan dalam tag aktor bernama di konfigurasi sistem.
  • config_signature . Overlay apa pun yang ditandatangani dengan tanda tangan yang sama dengan apk overlay-config dapat menggantikan sumber daya. Overlay-config dideklarasikan dalam tag overlay-config-signature di konfigurasi sistem.

Kode berikut menampilkan contoh <policy> di file res/values/overlayable.xml .

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

Untuk menentukan beberapa kebijakan, gunakan bilah vertikal (|) sebagai karakter pemisah. Ketika beberapa kebijakan ditentukan, overlay hanya perlu memenuhi satu kebijakan untuk mengganti sumber daya yang tercantum dalam tag <policy> .

Mengonfigurasi overlay

Android mendukung berbagai mekanisme untuk mengonfigurasi mutabilitas, status default, dan prioritas overlay bergantung pada versi rilis Android.

  • Perangkat yang menjalankan Android 11 atau lebih tinggi dapat menggunakan file OverlayConfig ( config.xml ) sebagai ganti atribut manifes. Menggunakan file overlay adalah metode yang disarankan untuk overlay.

  • Semua perangkat dapat menggunakan atribut manifes ( android:isStatic dan android:priority ) untuk mengonfigurasi RRO statis.

Menggunakan OverlayConfig

Di Android 11 atau lebih tinggi, Anda bisa menggunakan OverlayConfig untuk mengonfigurasi mutabilitas, status default, dan prioritas overlay. Untuk mengonfigurasi overlay, buat atau ubah file yang terletak di partition/overlay/config/config.xml , di mana partition adalah partisi overlay yang akan dikonfigurasi. Agar dapat dikonfigurasi, overlay harus berada di direktori overlay/ dari partisi tempat overlay dikonfigurasi. Kode berikut menunjukkan contoh 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>"

Tag <overlay> memerlukan atribut package yang menunjukkan paket overlay mana yang sedang dikonfigurasi. Atribut enabled opsional mengontrol apakah overlay diaktifkan atau tidak secara default (default adalah false ). Atribut opsional yang mutable mengontrol apakah overlay dapat diubah atau tidak dan status pengaktifannya dapat diubah secara terprogram saat runtime (standarnya adalah true ). Hamparan yang tidak tercantum dalam file konfigurasi dapat diubah dan dinonaktifkan secara default.

Prioritas overlay

Saat beberapa overlay menggantikan sumber daya yang sama, urutan overlay menjadi penting. Hamparan memiliki prioritas lebih tinggi daripada hamparan dengan konfigurasi yang mendahului konfigurasinya sendiri. Urutan prioritas overlay di partisi yang berbeda (dari prioritas terkecil hingga terbesar) adalah sebagai berikut.

  • system
  • vendor
  • odm
  • oem
  • product
  • system_ext

Menggabungkan file

Menggunakan <merge> memungkinkan file konfigurasi lain digabungkan pada posisi yang ditentukan ke dalam file konfigurasi. Atribut path dari tag mewakili jalur file yang akan digabungkan relatif terhadap direktori yang berisi file konfigurasi overlay.

Menggunakan atribut manifes (RRO statis)

Di Android 10 atau lebih rendah, kekekalan dan prioritas overlay dikonfigurasi menggunakan atribut manifes berikut.

  • android:isStatic . Bila nilai atribut boolean ini disetel ke true , overlay diaktifkan secara default dan tidak dapat diubah, yang mencegah overlay dinonaktifkan.

  • android:priority . Nilai atribut numerik ini (yang hanya memengaruhi overlay statis) mengonfigurasi prioritas overlay saat beberapa overlay statis menargetkan nilai sumber daya yang sama. Angka yang lebih tinggi menunjukkan prioritas yang lebih tinggi.

Kode berikut menunjukkan contoh 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>

Perubahan di Android 11

Di Android 11 atau lebih tinggi, jika file konfigurasi terletak di partition/overlay/config/config.xml , overlay dikonfigurasi menggunakan file tersebut dan android:isStatic dan android:priority tidak berpengaruh pada overlay yang terletak di partisi. Menentukan file konfigurasi overlay di partisi mana pun memberlakukan prioritas partisi overlay.

Selain itu, Android 11 atau lebih tinggi menghilangkan kemampuan untuk menggunakan overlay statis untuk memengaruhi nilai resource yang dibaca selama penginstalan paket. Untuk kasus penggunaan umum overlay statis untuk mengubah nilai boolean yang mengonfigurasi status aktif komponen, gunakan tag SystemConfig <component-override> (baru di Android 11).

Men-debug overlay

Untuk mengaktifkan, menonaktifkan, dan membuang overlay secara manual, gunakan perintah shell pengelola overlay berikut.

adb shell cmd overlay

OverlayManagerService menggunakan idmap2 untuk memetakan ID sumber daya dalam paket target ke ID sumber daya dalam paket overlay. Pemetaan ID yang dihasilkan disimpan di /data/resource-cache/ . Jika overlay Anda tidak berfungsi dengan benar, cari file idmap yang sesuai untuk overlay Anda di /data/resource-cache/ , lalu jalankan perintah berikut.

adb shell idmap2 dump --idmap-path [file]

Perintah ini mencetak pemetaan sumber daya seperti yang ditunjukkan di bawah ini.

[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType