रनटाइम के दौरान किसी ऐप्लिकेशन के संसाधनों की वैल्यू बदलना

रनटाइम रिसॉर्स ओवरले (आरआरओ) एक ऐसा पैकेज है जो रिसॉर्स की वैल्यू में बदलाव करता है का इस्तेमाल करें. उदाहरण के लिए, सिस्टम पर इंस्टॉल किया गया कोई ऐप्लिकेशन किसी संसाधन की वैल्यू के आधार पर, इमेज अपने व्यवहार में बदलाव कर सकती है. इसके बजाय बिल्ड टाइम पर रिसॉर्स वैल्यू की हार्डकोडिंग करते हैं, तो 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 पर सेट किया गया.

संसाधनों वाले मैप को तय करना

Android 11 या उसके बाद वाले वर्शन में, Android 11 या उसके बाद वाले वर्शन के लिए, ओवरले रिसॉर्स मैप तय करने से, res/xml में फ़ाइल बनती है ओवरले पैकेज की डायरेक्ट्री में, उन टारगेट रिसॉर्स की सूची बनाएं जिन्हें और उनके बदले जाने वाली वैल्यू तय करें. इसके बाद, किसी रेफ़रंस के लिए, <overlay> मेनिफ़ेस्ट टैग का android:resourcesMap एट्रिब्यूट संसाधन मैपिंग फ़ाइल को डाउनलोड करें.

यहां दिया गया कोड, 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 या उसके बाद के वर्शन के लिए, सूंग बिल्ड नियम जोड़ा जा सकता है: ऐसे ओवरले जो Android ऐसेट पैकेजिंग टूल 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 सिंटैक्स का इस्तेमाल करें.

ओवरले चालू/बंद करें

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

ओवरले किए जा सकने वाले संसाधनों पर पाबंदी लगाएं

Android 10 या उसके बाद के वर्शन में, <overlayable> एक्सएमएल टैग, संसाधनों का एक सेट दिखाता है कि आरआरओ को ओवरले करने की अनुमति है. नीचे दिए गए उदाहरण में 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. ओईएम पार्टीशन पर मौजूद कोई भी ओवरले, रिसॉर्स को बदल सकता है.
  • odm. ओडीएम पार्टीशन पर कोई भी ओवरले होने पर संसाधनों को बदला जा सकता है.
  • signature. टारगेट APK जैसे हस्ताक्षर से साइन किया गया कोई भी ओवरले संसाधनों को ओवरराइड न करें.
  • actor. actor APK के हस्ताक्षर से हस्ताक्षर किया गया कोई भी ओवरले संसाधनों को ओवरराइड न करें. कलाकार का नाम सिस्टम में named-actor टैग में बताया गया है कॉन्फ़िगरेशन.
  • config_signature. कोई भी ओवरले, जिस पर overlay-config apk संसाधनों को ओवरराइड कर सकता है. ओवरले कॉन्फ़िगरेशन यह है सिस्टम कॉन्फ़िगरेशन में, 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 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 एट्रिब्यूट शामिल होने वाली डायरेक्ट्री के मुताबिक मर्ज की जाने वाली फ़ाइल का पाथ दिखाता है ओवरले कॉन्फ़िगरेशन फ़ाइलें हैं.

मेनिफ़ेस्ट एट्रिब्यूट/स्टैटिक आरआरओ का इस्तेमाल करना

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

ओवरले डीबग करें

ओवरले को मैन्युअल रूप से चालू, बंद, और डंप करने के लिए, नीचे दिए गए ओवरले का इस्तेमाल करें मैनेजर शेल कमांड.

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