Runtime resource overlay (RRO) adalah paket yang mengubah nilai resource paket target saat runtime. Misalnya, aplikasi yang diinstal pada image sistem dapat mengubah perilakunya berdasarkan nilai resource. Daripada melakukan hardcoding nilai resource pada waktu build, RRO yang diinstal di partisi lain dapat mengubah nilai resource aplikasi saat runtime.
RRO dapat diaktifkan atau dinonaktifkan. Anda dapat menetapkan status enable/disable secara terprogram untuk mengalihkan kemampuan RRO guna mengubah nilai resource. RRO dinonaktifkan secara default (tetapi, RRO statis diaktifkan secara default).
Resource overlay
Overlay berfungsi dengan memetakan resource yang ditentukan dalam paket overlay ke resource yang ditentukan dalam paket target. Saat aplikasi mencoba me-resolve nilai resource dalam paket target, nilai resource overlay yang dipetakan ke resource target akan ditampilkan.
Menyiapkan manifes
Paket dianggap sebagai paket RRO jika berisi tag <overlay>
sebagai
turunan tag <manifest>
.
Nilai atribut
android:targetPackage
yang diperlukan menentukan nama paket yang ingin di-overlay oleh RRO.Nilai atribut
android:targetName
opsional menentukan nama subset resource yang dapat ditempatkan dari paket target yang ingin ditempatkan oleh RRO. Jika target tidak menentukan kumpulan resource yang dapat ditempatkan, atribut ini tidak boleh ada.
Kode berikut menunjukkan 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>
Overlay tidak dapat menempatkan kode, sehingga tidak dapat memiliki file DEX. Selain itu, atribut android:hasCode
dari tag <application
> dalam manifes harus
ditetapkan ke false
.
Menentukan peta resource
Di Android 11 atau yang lebih tinggi, mekanisme yang direkomendasikan untuk
menentukan peta resource overlay adalah membuat file di direktori res/xml
paket overlay, menghitung resource target yang harus
ditumpangkan dan nilai penggantiannya, lalu menetapkan nilai
atribut android:resourcesMap
dari tag manifes <overlay>
ke referensi
ke file pemetaan resource.
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 menunjukkan 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>
Mem-build paket
Android 11 atau yang lebih tinggi mendukung aturan build Soong untuk
overlay yang mencegah Android Asset Packaging Tool 2 (AAPT2) mencoba
menghapus duplikat konfigurasi resource dengan nilai yang sama
(--no-resource-deduping
) dan menghapus resource tanpa konfigurasi
default (--no-resource-removal
). Kode berikut menunjukkan contoh
file Android.bp
.
runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
Me-resolve resource
Jika resource target atau resource overlay memiliki beberapa konfigurasi yang ditentukan untuk resource yang dikueri, runtime resource akan menampilkan nilai konfigurasi yang paling cocok dengan konfigurasi konfigurasi perangkat. Untuk menentukan konfigurasi mana yang merupakan konfigurasi yang paling cocok, gabungkan kumpulan konfigurasi resource overlay ke dalam kumpulan konfigurasi resource target, lalu ikuti alur resolusi resource reguler (untuk mengetahui detailnya, lihat Cara Android menemukan resource 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
dipilih saat runtime. Untuk menempatkan semua konfigurasi drawable-en
, overlay
harus menentukan nilai untuk setiap konfigurasi drawable-en
yang ditentukan target.
Overlay dapat mereferensikan resource-nya sendiri, dengan perilaku yang berbeda antara rilis Android.
Di Android 11 atau yang lebih tinggi, setiap overlay memiliki ruang ID resource yang dicadangkan sendiri yang tidak tumpang-tindih dengan ruang ID resource target atau ruang ID resource overlay lainnya, sehingga overlay yang mereferensikan resourcenya sendiri berfungsi seperti yang diharapkan.
Di Android 10 atau yang lebih lama, overlay dan paket target berbagi ruang ID resource yang sama, yang dapat menyebabkan konflik dan perilaku yang tidak terduga saat mencoba mereferensikan resource-nya sendiri menggunakan sintaksis
@type/name
.
Mengaktifkan/menonaktifkan overlay
Overlay dapat diaktifkan/dinonaktifkan secara manual dan terprogram.
Menonaktifkan atau mengaktifkan overlay secara manual
Untuk mengaktifkan dan memverifikasi RRO secara manual, jalankan:
adb shell cmd overlay enable --user current com.example.carrro
adb shell cmd overlay list --user current | grep -i com.example com.example.carrro
Tindakan ini akan mengaktifkan RRO untuk pengguna sistem (userId = 0
) yang memiliki SystemUI.
Petunjuk ini tidak memengaruhi aplikasi yang dimulai oleh pengguna latar depan
(userId = 10
). Untuk mengaktifkan RRO bagi pengguna latar depan, gunakan
parameter -–user 10
:
adb shell cmd overlay enable --user 10 com.example.carrro
Mengaktifkan atau menonaktifkan overlay secara terprogram
Gunakan OverlayManager
API untuk mengaktifkan dan menonaktifkan overlay yang dapat diubah (ambil
antarmuka API menggunakan Context#getSystemService(Context.OVERLAY_SERVICE)
). Overlay
hanya dapat diaktifkan oleh paket yang ditargetkannya atau oleh paket dengan
izin android.permission.CHANGE_OVERLAY_PACKAGES
. Saat overlay
diaktifkan atau dinonaktifkan, peristiwa perubahan konfigurasi akan diterapkan ke paket target
dan aktivitas target akan diluncurkan ulang.
Membatasi resource yang dapat ditempatkan
Di Android 10 atau yang lebih baru, tag XML <overlayable>
mengekspos kumpulan resource
yang diizinkan untuk ditempatkan oleh RRO. Dalam contoh file
res/values/overlayable.xml
berikut, string/foo
dan integer/bar
adalah resource
yang digunakan untuk tema tampilan perangkat; untuk menempatkan resource ini, overlay
harus secara eksplisit menargetkan kumpulan resource yang dapat ditempatkan 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 tag <overlayable>
, tetapi setiap tag harus memiliki nama
unik dalam paket. Misalnya, nilainya adalah:
Mengizinkan dua paket yang berbeda untuk menentukan
<overlayable name="foo">
.Tidak boleh ada dua blok
<overlayable name="foo">
dalam satu APK.
Kode berikut menunjukkan contoh overlay dalam 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 yang menargetkan aplikasi tersebut:
Harus menentukan
targetName
.Hanya dapat menempatkan resource yang tercantum dalam tag
<overlayable>
.Hanya dapat menargetkan satu nama
<overlayable>
.
Anda tidak dapat mengaktifkan overlay yang menargetkan paket yang mengekspos resource
yang dapat di-overlay, tetapi tidak menggunakan android:targetName
untuk menargetkan tag
<overlayable>
tertentu.
Kebijakan pembatasan
Gunakan tag <policy>
untuk menerapkan batasan pada resource yang dapat ditempatkan. Atribut
type
menentukan kebijakan yang harus dipenuhi overlay untuk mengganti
resource yang disertakan. Jenis yang didukung mencakup hal berikut.
public
. Overlay apa pun dapat mengganti resource.system
. Setiap overlay pada partisi sistem dapat mengganti resource.vendor
. Setiap overlay pada partisi vendor dapat mengganti resource.product
. Setiap overlay pada partisi produk dapat mengganti resource.oem
. Setiap overlay pada partisi OEM dapat mengganti resource.odm
. Setiap overlay pada partisi odm dapat mengganti resource.signature
. Setiap overlay yang ditandatangani dengan tanda tangan yang sama dengan APK target dapat mengganti resource.actor
. Setiap overlay yang ditandatangani dengan tanda tangan yang sama dengan APK aktor dapat mengganti resource. Aktor dideklarasikan dalam tag named-actor dalam konfigurasi sistem.config_signature
. Setiap overlay yang ditandatangani dengan tanda tangan yang sama dengan apk overlay-config dapat mengganti resource. Konfigurasi overlay dideklarasikan dalam tag overlay-config-signature di konfigurasi sistem.
Kode berikut menunjukkan contoh tag <policy>
dalam
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 garis vertikal (|) sebagai karakter pemisah.
Jika beberapa kebijakan ditentukan, overlay hanya perlu memenuhi satu
kebijakan untuk mengganti resource 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 yang lebih tinggi dapat menggunakan file
OverlayConfig
(config.xml
), bukan atribut manifes. Menggunakan file overlay adalah metode yang direkomendasikan untuk overlay.Semua perangkat dapat menggunakan atribut manifes (
android:isStatic
danandroid:priority
) untuk mengonfigurasi RRO statis.
Menggunakan OverlayConfig
Di Android 11 atau yang lebih baru, Anda dapat 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
, dengan partition
adalah partisi
overlay yang akan dikonfigurasi. Agar dapat dikonfigurasi, overlay harus berada di
direktori overlay/
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
yang sedang dikonfigurasi. Atribut enabled
opsional mengontrol apakah
overlay diaktifkan secara default atau tidak (defaultnya adalah false
). Atribut
mutable
opsional mengontrol apakah overlay dapat diubah atau tidak dan dapat
mengubah status pengaktifannya secara terprogram saat runtime (defaultnya adalah true
).
Overlay yang tidak tercantum dalam file konfigurasi dapat diubah dan dinonaktifkan secara
default.
Prioritas overlay
Jika beberapa overlay mengganti resource yang sama, urutan overlay sangat penting. Overlay memiliki prioritas yang lebih besar daripada overlay dengan konfigurasi yang mendahului konfigurasinya sendiri. Urutan prioritas overlay dalam berbagai partisi (dari prioritas paling kecil hingga paling besar) adalah sebagai berikut.
system
vendor
odm
oem
product
system_ext
Menggabungkan file
Penggunaan tag <merge>
memungkinkan file konfigurasi lain digabungkan pada posisi yang ditentukan ke dalam file konfigurasi. Atribut path
tag
mewakili jalur file yang akan digabungkan secara relatif terhadap direktori yang berisi
file konfigurasi overlay.
Menggunakan atribut manifes/RRO statis
Di Android 10 atau yang lebih lama, ketidakmutlakan dan prioritas overlay dikonfigurasi menggunakan atribut manifes berikut.
android:isStatic
. Jika nilai atribut boolean ini ditetapkan ketrue
, overlay diaktifkan secara default dan tidak dapat diubah, sehingga mencegah overlay dinonaktifkan.android:priority
. Nilai atribut numerik ini (yang hanya memengaruhi overlay statis) mengonfigurasi prioritas overlay saat beberapa overlay statis menargetkan nilai resource yang sama. Angka yang lebih tinggi menunjukkan precedence 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 yang lebih tinggi, jika file konfigurasi
berada di partition/overlay/config/config.xml
, overlay dikonfigurasi menggunakan
file tersebut dan android:isStatic
serta android:priority
tidak berpengaruh pada
overlay yang berada di partisi. Menentukan file konfigurasi overlay di
partisi mana pun akan menerapkan prioritas partisi overlay.
Selain itu, Android 11 atau yang lebih tinggi menghapus kemampuan
untuk menggunakan overlay statis guna memengaruhi nilai resource yang dibaca selama penginstalan
paket. Untuk kasus penggunaan umum penggunaan overlay statis guna mengubah
nilai boolean yang mengonfigurasi status pengaktifan komponen, gunakan
tag <component-override>
SystemConfig
(baru di Android
11).
Overlay debug
Untuk mengaktifkan, menonaktifkan, dan membuang overlay secara manual, gunakan perintah shell pengelola overlay berikut.
adb shell cmd overlay
Menggunakan enable
tanpa menentukan pengguna akan memengaruhi pengguna saat ini, yaitu
pengguna sistem (userId = 0
), yang memiliki UI Sistem. Hal ini tidak memengaruhi
pengguna latar depan (userId = 10
), yang memiliki aplikasi. Untuk mengaktifkan RRO bagi
pengguna latar depan, gunakan parameter –-user 10
:
adb shell cmd overlay enable --user 10 com.example.carrro
OverlayManagerService
menggunakan idmap2
untuk memetakan ID resource dalam paket
target ke ID resource dalam paket overlay. Pemetaan ID yang dihasilkan
disimpan di /data/resource-cache/
. Jika overlay Anda tidak berfungsi dengan benar, temukan
file idmap
yang sesuai untuk overlay Anda di /data/resource-cache/
, lalu
jalankan perintah berikut.
adb shell idmap2 dump --idmap-path [file]
Perintah ini akan mencetak pemetaan resource seperti yang ditunjukkan di bawah.
[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType