שכבת-על של משאבים בזמן ריצה (RRO) היא חבילה שמשנה את ערכי המשאבים של חבילת יעד בזמן הריצה. לדוגמה, אפליקציה שמותקנת במערכת על סמך הערך של המשאב, התמונה עשויה לשנות את ההתנהגות שלה. במקום לכתוב בתוך הקוד את ערך המשאב בזמן ה-build, RRO המותקן יכול לשנות את הערכים של משאבי האפליקציה בזמן הריצה.
אפשר להפעיל או להשבית RROs. אפשר להגדיר באופן פרוגרמטי את הפעלה/השבתה של מצב כדי להפעיל או להשבית את היכולת של RRO לשנות ערכי משאבים. RRO מושבתים כברירת מחדל (עם זאת, RROs סטטיים מופעלים על ידי כברירת מחדל).
משאבים בשכבת-על
שכבות-על פועלות על ידי מיפוי משאבים שמוגדרים בחבילת שכבת-העל למשאבים מוגדר בחבילת היעד. כשאפליקציה מנסה לחשב את הערך של המשאב בחבילת היעד, הערך של משאב שכבת-העל שהיעד במקום זאת, המשאב ממופה אל.
הגדרת המניפסט
חבילה נחשבת לחבילת RRO אם היא מכילה תג <overlay>
בתור
צאצא של התג <manifest>
.
הערך של מאפיין החובה
android:targetPackage
מציין את השם של החבילה שה-RRO מתכוון ליצור שכבת-על.הערך של המאפיין האופציונלי
android:targetName
מציין את השם של את קבוצת המשאבים הניתנת לשכבת-על של חבילת היעד שה-RRO מתכוון בשכבת-על. אם היעד לא מגדיר קבוצת משאבים שניתן שכבת-על, לא יכול להיות קיים.
הקוד הבא מציג שכבת-על לדוגמה 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>
שכבות-על לא יכולות להוסיף קוד כשכבת-על, ולכן הן לא יכולות לכלול קובצי DEX. בנוסף,
מאפיין android:hasCode
של <application
> במניפסט צריך להיות
מוגדר ל-false
.
הגדרה של מפת המשאבים
ב-Android מגרסה 11 ואילך, המנגנון המומלץ עבור
ההגדרה של מפת המשאבים בשכבת-על היא ליצור קובץ בres/xml
של חבילת שכבת-העל, מספורים את משאבי היעד שאמורים להיות
כשכבת-על ואת הערכים החלופיים שלהם, ואז להגדיר את הערך
מאפיין android:resourcesMap
של תג המניפסט <overlay>
לקובץ עזר
לקובץ מיפוי המשאבים.
הקוד הבא מציג קובץ 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>
הקוד הבא מציג דוגמה למניפסט של שכבת-על.
<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>
הרכבת החבילה
במכשירי Android בגרסה 11 ואילך יש תמיכה בכלל build של Sog
שכבות-על שמונעות מהכלי 2 (AAPT2) לאריזת נכסים של Android לנסות
הגדרות של ביטול כפילויות של משאבים עם אותו ערך
(--no-resource-deduping
) ומהסרת משאבים ללא ברירת מחדל
הגדרות אישיות (--no-resource-removal
). הקוד הבא מציג דוגמה
קובץ Android.bp
.
runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
טיפול במשאבים
אם למשאב יעד או למשאב של שכבת-על יש כמה תצורות שנקבעו של המשאב שלגביו נשלחת השאילתה, סביבת זמן הריצה של המשאבים מחזירה את הערך את התצורה שהכי מתאימה להגדרות של המכשיר. כדי לקבוע איזו תצורה היא המתאימה ביותר, ממזגים את של הגדרות משאבי שכבת-העל בקבוצה של משאבי היעד ואז לפעול בהתאם לתהליך הרגיל של רזולוציית המשאבים (ל אפשר לקרוא פרטים נוספים במאמר איך מערכת Android מוצאת את ההתאמה הטובה ביותר? משאב).
לדוגמה, אם שכבת-על מגדירה ערך להגדרה drawable-en
והיעד מגדיר את הערך של drawable-en-port
, drawable-en-port
יש התאמה טובה יותר, כך שהערך של הגדרת היעד drawable-en-port
נבחר בזמן הריצה. כדי ליצור שכבת-על לכל drawable-en
התצורות, שכבת-העל
חייבים להגדיר ערך לכל הגדרת drawable-en
שהיעד מגדיר.
שכבות-על יכולות להפנות למשאבים שלהן, עם התנהגויות שונות גרסאות של Android.
ב-Android מגרסה 11 ואילך, לכל שכבת-על יש משלה מרחב שמור למזהה משאב שאינו חופף למרחב היעד של מזהה המשאב, או שכבות-על אחרות של מזהי משאבים קיימים, כך ששכבות-על מפנות למשאבים שלהם פועלות כמצופה.
ב-Android מגרסה 10 ומטה, שכבות-על וחבילות יעד חולקות את אותו משאב מרחב מזהה, שעלולות לגרום להתנגשויות ולהתנהגות לא צפויה כשהם ינסו להפנות למשאבים שלהם באמצעות התחביר
@type/name
.
הפעלה/השבתה של שכבות-על
שימוש ב-API של OverlayManager
כדי להפעיל ולהשבית שכבות-על שניתנות לשינוי (אחזור
ממשק ה-API באמצעות Context#getSystemService(Context.OVERLAY_SERVICE)
).
שכבת-על יכולה להיות מופעלת רק על ידי החבילה שאליה היא מטרגטת או על ידי חבילה עם
הרשאת android.permission.CHANGE_OVERLAY_PACKAGES
. כששכבת-על היא
מופעלת או מושבתת, אירועי שינוי של הגדרות אישיות יועברו לחבילת היעד
להפעיל מחדש את פעילויות היעד.
הגבלת משאבים שניתנים לשכבת-על
ב-Android מגרסה 10 ואילך, תג ה-XML מסוג <overlayable>
חושף קבוצת משאבים
ש-RRO יכולים ליצור שכבת-על. בדוגמה הבאה
קובץ res/values/overlayable.xml
, string/foo
ו-integer/bar
הם משאבים
משמש לסיווג המכשיר. ליצירת שכבות-על
חייב להתמקד במפורש באוסף משאבים שניתן לשכבת-על לפי שם.
<!-- 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 אפשר להגדיר כמה תגי <overlayable>
, אבל לכל תג צריך להיות
בתוך החבילה. לדוגמה:
אוקיי, שתי חבילות שונות מגדירות את
<overlayable name="foo">
.לא מתאים ל-APK יחיד לכלול שתי חסימות של
<overlayable name="foo">
.
הקוד הבא מציג דוגמה לשכבת-על בקובץ 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>
כשאפליקציה מגדירה תג <overlayable>
, שכבות-על שמטרגטות את האפליקציה הזו:
יש לציין את
targetName
.אפשר להגדיר שכבת-על רק למשאבים שרשומים בתג
<overlayable>
.ניתן לטרגט רק שם אחד של
<overlayable>
.
לא ניתן להפעיל שכבת-על שמטרגטת חבילה שחושפת שכבת-על
משאבים, אבל לא משתמש ב-android:targetName
כדי לטרגט
תג <overlayable>
.
הגבלת המדיניות
שימוש בתג <policy>
כדי לאכוף הגבלות על משאבים שניתן להוסיף שכבת-על.
המאפיין type
מציין אילו כללי מדיניות שכבת-על צריכה למלא כדי לשנות מברירת המחדל
את המשאבים הכלולים. הסוגים הנתמכים כוללים את אלה.
public
כל שכבת-על יכולה לעקוף את המשאב.system
כל שכבת-על במחיצת המערכת יכולה לעקוף את המשאבים.vendor
כל שכבת-על במחיצת הספק יכולה לבטל את המשאבים.product
כל שכבת-על במחיצת המוצרים יכולה לבטל את המשאבים.oem
כל שכבת-על במחיצת ה-OEM יכולה לעקוף את המשאבים.odm
כל שכבת-על במחיצת ה-odm יכולה לעקוף את המשאבים.signature
כל שכבת-על עם חתימה זהה לזו של APK היעד יכולה לשנות את המשאבים.actor
כל שכבת-על עם אותה חתימה כמו זו של ה-APK של השחקן יכולה לשנות את המשאבים. המשתמש מוצהר בתג named-actor במערכת הגדרהconfig_signature
כל שכבת-על שחתומה עם אותה חתימה כמו ה-APK overlay-config יכול לעקוף את המשאבים. הגדרת שכבת-העל היא הוצהרה בתג overlay-config-signature בהגדרות המערכת.
הקוד הבא מציג תג <policy>
לדוגמה
קובץ 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>
כדי לציין כמה כללי מדיניות, צריך להשתמש בקווים אנכיים (|) בתור תווים מפרידים.
אם מציינים כמה כללי מדיניות, שכבת-על צריכה למלא רק תנאי אחד
כדי לשנות את המשאבים המפורטים בתג <policy>
.
הגדרת שכבות-על
מערכת Android תומכת במנגנונים שונים להגדרת יכולת ההשתנות, ברירת המחדל המצב והעדיפות של שכבות-על, בהתאם לגרסת הגרסה של Android.
מכשירים עם Android מגרסה 11 ואילך יכולים להשתמש קובץ
OverlayConfig
(config.xml
) במקום מאפייני המניפסט. שימוש ב קובץ שכבת-על הוא השיטה המומלצת ליצירת שכבות-על.בכל המכשירים אפשר להשתמש במאפייני מניפסט (
android:isStatic
וגםandroid:priority
) כדי להגדיר תקנות RRO סטטיות.
שימוש ב-OverlayConfig
ב-Android מגרסה 11 ואילך, אפשר להשתמש ב-OverlayConfig
כדי
להגדיר את יכולת השינוי, מצב ברירת המחדל והעדיפות של שכבות-על. כדי להגדיר
שכבת-על, ליצור או לשנות את הקובץ שנמצא בכתובת
partition/overlay/config/config.xml
, כאשר partition
היא המחיצה של
שכבת-על להגדרה. כדי להגדיר שכבת-על,
הספרייה overlay/
של המחיצה שבה מוגדרת שכבת-העל.
הקוד הבא מציג דוגמה 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>
נדרש מאפיין package
שמציין איזו שכבת-על
החבילה נמצאת בתהליך הגדרה. המאפיין האופציונלי enabled
קובע אם
או לא, שכבת-העל מופעלת כברירת מחדל (ברירת המחדל היא false
). הערכים האופציונליים
המאפיין mutable
קובע אם שכבת-העל ניתנת לשינוי ויכולה לכלול
המצב המופעל שלו השתנה באופן פרוגרמטי בזמן הריצה (ברירת המחדל היא true
).
שכבות-על שלא מופיעות בקובץ תצורה ניתנות לשינוי ומושבתות על ידי
כברירת מחדל.
קדימות של שכבת-על
כאשר שכבות-על מרובות מבטלות את אותם משאבים, הסדר של שכבות-העל הוא חשוב. לשכבת-על יש קדימות יותר מאשר לשכבות-על עם הגדרות אישיות לפני ההגדרה שלו. סדר הקדימות של שכבות-על בפורמט שונה הבאות:
system
vendor
odm
oem
product
system_ext
מיזוג קבצים
השימוש בתגי <merge>
מאפשר למזג קובצי תצורה אחרים
את המיקום שצוין בקובץ התצורה. מאפיין path
של התג
מייצג את נתיב הקובץ למיזוג ביחס לספרייה שמכילה
קובצי תצורה של שכבות-על.
שימוש במאפייני מניפסט או ברכיבי RRO סטטיים
ב-Android מגרסה 10 ומטה, שכבות-על לא ניתנות לשינוי וקדימות מוגדרות באמצעות את מאפייני המניפסט הבאים.
android:isStatic
כשהערך של המאפיין הבוליאני הזה מוגדר ל-true
, שכבת-העל מופעלת כברירת מחדל ואי אפשר לשנות אותה, ולכן שכבת-העל מהשבתה.android:priority
הערך של המאפיין המספרי הזה (שמשפיע רק על שכבות-על סטטיות) מגדיר את הקדימות של שכבת-העל כאשר שכבות-על מטרגטות אותו ערך של משאב. מספר גבוה יותר מצביע על ערך גבוה יותר בעדיפות גבוהה.
הקוד הבא מציג דוגמה ל-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
ב-Android מגרסה 11 ואילך, אם קובץ תצורה
ב-partition/overlay/config/config.xml
, שכבות-על מוגדרות באמצעות
לקובץ הזה ול-android:isStatic
ול-android:priority
אין השפעה על
שכבות-על שנמצאות במחיצה. הגדרת קובץ תצורה של שכבת-על בכל
אוכפת הקדימות של מחיצות שכבת-על.
כמו כן, מערכת Android מגרסה 11 ואילך מסירה את האפשרות
כדי להשתמש בשכבות-על סטטיות כדי להשפיע על הערכים של המשאבים שנקראים במהלך החבילה
בתהליך ההתקנה. בתרחיש לדוגמה נפוץ של שימוש בשכבות-על סטטיות כדי לשנות את
בערך של בוליאני שמגדיר את המצב שמופעל של הרכיב, השתמש ב-
תג SystemConfig
אחד (<component-override>
) (חדש ב-Android
11).
שכבות-על של ניפוי באגים
כדי להפעיל, להשבית ולהעביר שכבות-על באופן ידני, צריך להשתמש בשכבת-העל הבאה פקודת מעטפת מנהל.
adb shell cmd overlay
ב-OverlayManagerService
נעשה שימוש ב-idmap2
כדי למפות מזהי משאבים ביעד
חבילה למזהי משאבים בחבילת שכבת-העל. מיפויי המזהים שנוצרו
מאוחסנים בתיקייה /data/resource-cache/
. אם שכבת-העל לא פועלת כראוי, מחפשים את
קובץ idmap
התואם לשכבת-העל שלך ב-/data/resource-cache/
, ואז
מריצים את הפקודה הבאה.
adb shell idmap2 dump --idmap-path [file]
הפקודה הזו מדפיסה את המיפוי של המשאבים, כפי שמוצג בהמשך.
[target res id] - > [overlay res id] [resource name]
0x01040151 -> 0x01050001 string/config_dozeComponent
0x01040152 -> 0x01050002 string/config_dozeDoubleTapSensorType
0x01040153 -> 0x01050003 string/config_dozeLongPressSensorType