تراكب مورد وقت التشغيل (RRO) هو حزمة تعمل على تغيير قيم الموارد للحزمة المستهدفة في وقت التشغيل. على سبيل المثال ، قد يغير أحد التطبيقات المثبتة على صورة النظام سلوكه بناءً على قيمة المورد. بدلاً من تشفير قيمة المورد في وقت الإنشاء ، يمكن لـ RRO المثبت على قسم مختلف تغيير قيم موارد التطبيق في وقت التشغيل.
يمكن تمكين أو تعطيل RROs. يمكنك تعيين حالة التمكين / التعطيل برمجيًا لتبديل قدرة RRO على تغيير قيم الموارد. يتم تعطيل RROs بشكل افتراضي (ومع ذلك ، يتم تمكين 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 أو إصدار أحدث قاعدة Soong للبناء للتراكبات التي تمنع Android Asset Packaging Tool 2 (AAPT2) من محاولة إلغاء تكوينات الموارد بنفس القيمة ( --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
syntax.
تمكين / تعطيل التراكبات
استخدم واجهة برمجة تطبيقات OverlayManager
لتمكين التراكبات القابلة للتغيير وتعطيلها (استرداد واجهة API باستخدام Context#getSystemService(Context.OVERLAY_SERVICE)
). لا يمكن تمكين التراكب إلا من خلال الحزمة التي تستهدفها أو من خلال حزمة بإذن android.permission.CHANGE_OVERLAY_PACKAGES
. عند تمكين التراكب أو تعطيله ، تنتشر أحداث تغيير التكوين إلى الحزمة المستهدفة وإعادة تشغيل الأنشطة المستهدفة.
تقييد الموارد القابلة للتراكب
في Android 10 أو إصدار أحدث ، تعرض علامة XML <overlayable>
مجموعة من الموارد التي يُسمح لـ RROs بتراكبها. في المثال التالي ملف 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 للممثل تجاوز الموارد. تم الإعلان عن الممثل في علامة فاعل مسمى في تكوين النظام. -
config_signature
. يمكن لأي تراكب موقع بنفس التوقيع مثل overlay-config apk تجاوز الموارد. يتم الإعلان عن التراكب-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
) لتهيئة RROs الثابتة.
باستخدام 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
للعلامة مسار الملف المراد دمجه بالنسبة إلى الدليل الذي يحتوي على ملفات تكوين التراكب.
استخدام سمات البيان (ثابت RROs)
في 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 أو أعلى القدرة على استخدام التراكبات الثابتة للتأثير على قيم الموارد التي تمت قراءتها أثناء تثبيت الحزمة. بالنسبة لحالة الاستخدام الشائعة لاستخدام التراكبات الثابتة لتغيير قيمة القيم المنطقية التي تهيئ حالة تمكين المكون ، استخدم علامة <component-override>
SystemConfig
(جديد في Android 11).
تراكبات التصحيح
لتمكين التراكبات وتعطيلها وتفريغها يدويًا ، استخدم أمر shell manager التالي.
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