रनटाइम पर किसी ऐप के संसाधनों का मान बदलें

संग्रह की मदद से व्यवस्थित रहें अपनी प्राथमिकताओं के आधार पर, कॉन्टेंट को सेव करें और कैटगरी में बांटें.

रनटाइम रिसोर्स ओवरले (आरआरओ) एक पैकेज है जो रनटाइम पर लक्ष्य पैकेज के संसाधन मान को बदलता है। उदाहरण के लिए, सिस्टम इमेज पर इंस्टॉल किया गया ऐप किसी संसाधन के मूल्य के आधार पर अपना व्यवहार बदल सकता है। बिल्ड समय पर संसाधन मान को हार्डकोड करने के बजाय, एक भिन्न पार्टीशन पर स्थापित RRO रनटाइम पर ऐप के संसाधनों के मान को बदल सकता है।

आरआरओ को सक्षम या अक्षम किया जा सकता है। आप संसाधन मूल्यों को बदलने के लिए RRO की क्षमता को टॉगल करने के लिए सक्षम/अक्षम स्थिति को प्रोग्रामेटिक रूप से सेट कर सकते हैं। आरआरओ डिफ़ॉल्ट रूप से अक्षम होते हैं (हालांकि, स्थिर आरआरओ डिफ़ॉल्ट रूप से सक्षम होते हैं)।

ओवरलेइंग संसाधन

लक्ष्य पैकेज में परिभाषित संसाधनों के लिए ओवरले पैकेज में परिभाषित संसाधनों को मैप करके ओवरले काम करता है। जब कोई ऐप लक्ष्य पैकेज में संसाधन के मूल्य को हल करने का प्रयास करता है, तो ओवरले संसाधन का मान जिसके लिए लक्ष्य संसाधन मैप किया जाता है, बदले में वापस आ जाता है।

मेनिफेस्ट की स्थापना

एक पैकेज को RRO पैकेज माना जाता है यदि इसमें <overlay> टैग <manifest> टैग के चाइल्ड के रूप में होता है।

  • आवश्यक android:targetPackage विशेषता का मान उस पैकेज का नाम निर्दिष्ट करता है जिसे RRO ओवरले करना चाहता है।

  • वैकल्पिक android:targetName विशेषता का मान लक्ष्य पैकेज के संसाधनों के ओवरलेएबल सबसेट का नाम निर्दिष्ट करता है जिसे आरआरओ ओवरले करना चाहता है। यदि लक्ष्य संसाधनों के ओवरलेएबल सेट को परिभाषित नहीं करता है, तो यह विशेषता मौजूद नहीं होनी चाहिए।

निम्न कोड एक उदाहरण ओवरले 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 फ़ाइलें नहीं हो सकतीं। इसके अलावा, मेनिफेस्ट में <application > टैग की android:hasCode विशेषता को false पर सेट किया जाना चाहिए।

संसाधनों के मानचित्र को परिभाषित करना

एंड्रॉइड 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>

पैकेज का निर्माण

एंड्रॉइड 11 या उच्चतर ओवरले के लिए सूंग बिल्ड नियम का समर्थन करता है जो एंड्रॉइड एसेट पैकेजिंग टूल 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 रिलीज़ के बीच अलग-अलग व्यवहारों के साथ, ओवरले अपने स्वयं के संसाधनों को संदर्भित कर सकते हैं।

  • एंड्रॉइड 11 या उच्चतर में, प्रत्येक ओवरले का अपना आरक्षित संसाधन आईडी स्थान होता है जो लक्ष्य संसाधन आईडी स्थान या अन्य ओवरले संसाधन आईडी स्थान को ओवरलैप नहीं करता है, इसलिए ओवरले अपने स्वयं के संसाधनों को संदर्भित करते हुए अपेक्षा के अनुरूप काम करते हैं।

  • एंड्रॉइड 10 या उससे पहले के संस्करण में, ओवरले और लक्ष्य पैकेज समान संसाधन आईडी स्थान साझा करते हैं, जो टकराव और अप्रत्याशित व्यवहार का कारण बन सकता है जब वे @type/name सिंटैक्स का उपयोग करके अपने स्वयं के संसाधनों को संदर्भित करने का प्रयास करते हैं।

ओवरले को सक्षम/अक्षम करना

म्यूटेबल ओवरले को सक्षम और अक्षम करने के लिए OverlayManager API का उपयोग करें ( Context#getSystemService(Context.OVERLAY_SERVICE) का उपयोग करके API इंटरफ़ेस पुनर्प्राप्त करें)। एक ओवरले को केवल उस पैकेज द्वारा सक्षम किया जा सकता है जिसे वह लक्षित करता है या android.permission.CHANGE_OVERLAY_PACKAGES अनुमति वाले पैकेज द्वारा। जब ओवरले को सक्षम या अक्षम किया जाता है, तो कॉन्फ़िगरेशन परिवर्तन ईवेंट लक्षित पैकेज और लक्ष्य गतिविधियों को पुन: लॉन्च करने के लिए प्रसारित होते हैं।

ओवरले करने योग्य संसाधनों को प्रतिबंधित करना

एंड्रॉइड 10 या उच्चतर में, <overlayable> XML टैग संसाधनों के एक सेट को उजागर करता है जिसे आरआरओ को ओवरले करने की अनुमति है। निम्नलिखित उदाहरण में 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>

एक एपीके एकाधिक <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> नाम को लक्षित कर सकता है।

आप किसी ऐसे पैकेज को लक्षित करने वाले ओवरले को सक्षम नहीं कर सकते हैं जो ओवरले करने योग्य संसाधनों को उजागर करता है लेकिन किसी विशिष्ट <overlayable> टैग को लक्षित करने के लिए android:targetName का उपयोग नहीं करता है।

नीतियों को प्रतिबंधित करना

ओवरले करने योग्य संसाधनों पर प्रतिबंध लागू करने के लिए <policy> टैग का उपयोग करें। type विशेषता निर्दिष्ट करती है कि शामिल संसाधनों को ओवरराइड करने के लिए ओवरले को किन नीतियों को पूरा करना होगा। समर्थित प्रकारों में निम्न शामिल हैं।

  • public । कोई भी ओवरले संसाधन को ओवरराइड कर सकता है।
  • system । सिस्टम विभाजन पर कोई ओवरले संसाधनों को ओवरराइड कर सकता है।
  • vendor । विक्रेता विभाजन पर कोई ओवरले संसाधनों को ओवरराइड कर सकता है।
  • product । उत्पाद विभाजन पर कोई ओवरले संसाधनों को ओवरराइड कर सकता है।
  • oem । ओम विभाजन पर कोई ओवरले संसाधनों को ओवरराइड कर सकता है।
  • odm । odm पार्टीशन पर कोई भी ओवरले संसाधनों को ओवरराइड कर सकता है।
  • signature । लक्ष्य APK के समान हस्ताक्षर से हस्ताक्षरित कोई भी ओवरले संसाधनों को ओवरराइड कर सकता है।
  • actorअभिनेता APK के समान हस्ताक्षर से हस्ताक्षरित कोई भी ओवरले संसाधनों को ओवरराइड कर सकता है। अभिनेता को सिस्टम कॉन्फ़िगरेशन में नाम-अभिनेता टैग में घोषित किया गया है।
  • config_signature . overlay-config apk के समान हस्ताक्षर से हस्ताक्षरित कोई भी ओवरले संसाधनों को ओवरराइड कर सकता है। ओवरले-कॉन्फ़िगरेशन सिस्टम कॉन्फ़िगरेशन में ओवरले-कॉन्फ़िगरेशन-सिग्नेचर टैग में घोषित किया गया है।

निम्न कोड res/values/overlayable.xml फ़ाइल में एक उदाहरण <policy> टैग दिखाता है।

<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 11 या उसके बाद वाले वर्शन चला रहे डिवाइस मेनिफेस्ट विशेषताओं के बजाय OverlayConfig फ़ाइल ( config.xml ) का उपयोग कर सकते हैं। ओवरले के लिए ओवरले फ़ाइल का उपयोग करने की अनुशंसा की जाती है।

  • स्थिर आरआरओ को कॉन्फ़िगर करने के लिए सभी डिवाइस मेनिफ़ेस्ट एट्रिब्यूट ( android:isStatic और android:priority ) का उपयोग कर सकते हैं।

ओवरले कॉन्फिग का उपयोग करना

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 विशेषता ओवरले कॉन्फ़िगरेशन फ़ाइलों वाली निर्देशिका के सापेक्ष विलय करने के लिए फ़ाइल के पथ का प्रतिनिधित्व करती है।

मेनिफेस्ट विशेषताओं का उपयोग करना (स्थिर आरआरओ)

एंड्रॉइड 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 में नया) का उपयोग करें।

डिबगिंग ओवरले

ओवरले को मैन्युअल रूप से सक्षम, अक्षम और डंप करने के लिए, निम्न ओवरले प्रबंधक शेल कमांड का उपयोग करें।

adb shell cmd overlay

OverlayManagerService लक्ष्य पैकेज में संसाधन आईडी को ओवरले पैकेज में संसाधन आईडी से मैप करने के लिए idmap2 का उपयोग करता है। जनरेट की गई आईडी मैपिंग को /data/resource-cache/ में स्टोर किया जाता है। यदि आपका ओवरले सही तरीके से काम नहीं कर रहा है, तो अपने ओवरले के लिए /data/resource-cache/ में संबंधित idmap फ़ाइल ढूंढें, फिर निम्न कमांड चलाएँ।

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