فایل های مانیفست را مدیریت کنید

این صفحه نحوه عملکرد ادغام مانیفست و نحوه اعمال تنظیمات برگزیده ادغام را برای حل تعارضات ادغام توضیح می دهد. برای آشنایی با فایل مانیفست برنامه، نمای کلی مانیفست برنامه را ببینید.

چندین فایل مانیفست را ادغام کنید

فایل APK یا Android App Bundle شما می‌تواند فقط یک فایل AndroidManifest.xml داشته باشد، اما پروژه Android Studio شما ممکن است حاوی چندین فایل مانیفست باشد که توسط مجموعه منبع اصلی، انواع ساخت و کتابخانه‌های وارد شده ارائه شده است. هنگام ساختن برنامه شما، ساخت Gradle همه فایل های مانیفست را در یک فایل مانیفست واحد که در برنامه شما بسته بندی شده است ادغام می کند.

ابزار ادغام مانیفست تمام عناصر XML را از هر فایل با پیروی از اکتشافی ادغام و پیروی از اولویت‌های ادغام که با ویژگی‌های خاص XML تعریف کرده‌اید، ترکیب می‌کند.

نکته: برای پیش نمایش نتایج مانیفست ادغام شده خود و یافتن خطاهای تضاد، از نمای Manifest ادغام شده ، که در بخش زیر توضیح داده شده است، استفاده کنید.

ادغام اولویت ها

ابزار ادغام، همه فایل‌های مانیفست را به صورت متوالی در یک فایل، بر اساس اولویت هر فایل مانیفست ترکیب می‌کند. به عنوان مثال، اگر سه فایل مانیفست دارید، مانیفست با کمترین اولویت در مانیفست با اولویت بعدی ادغام می شود و سپس در مانیفست با بالاترین اولویت، همانطور که در شکل 1 نشان داده شده است، ادغام می شود.

شکل 1. فرآیند ادغام سه فایل مانیفست با کمترین اولویت به بالاترین اولویت.

سه نوع اصلی از فایل های مانیفست وجود دارد که ممکن است در یکدیگر ادغام شوند، و اولویت های ادغام آنها به شرح زیر است (اول بالاترین اولویت):

  1. فایل مانیفست برای نوع ساخت شما

    اگر چندین مجموعه منبع برای نوع خود دارید، اولویت های آشکار آنها به شرح زیر است:

    • مانیفست نوع ساخت (مانند src/demoDebug/ )
    • مانیفست نوع ساخت (مانند src/debug/ )
    • عطر و طعم محصول آشکار می شود (مانند src/demo/ )

      اگر از ابعاد طعم استفاده می کنید، اولویت های مانیفست مطابق با ترتیبی است که هر بعد در ویژگی flavorDimensions فهرست شده است (اول بالاترین اولویت است).

  2. فایل مانیفست اصلی برای ماژول برنامه
  3. فایل مانیفست از یک کتابخانه شامل

    اگر چندین کتابخانه دارید، اولویت‌های مانیفست آنها با ترتیبی که در بلوک dependencies Gradle شما ظاهر می‌شوند مطابقت دارد.

برای مثال، یک مانیفست کتابخانه ای در مانیفست اصلی ادغام می شود، سپس مانیفست اصلی در مانیفست نوع ساخت ادغام می شود. توجه داشته باشید که اینها همان اولویت های ادغام برای همه مجموعه های منبع هستند، همانطور که در ساخت با مجموعه های منبع توضیح داده شده است.

مهم: پیکربندی‌های ساخت از فایل build.gradle هر ویژگی مربوطه را در فایل مانیفست ادغام‌شده لغو می‌کند. به عنوان مثال، minSdk از فایل build.gradle یا build.gradle.kts ویژگی تطبیق را در عنصر مانیفست <uses-sdk> لغو می کند. برای جلوگیری از سردرگمی، عنصر <uses-sdk> را کنار بگذارید و این ویژگی ها را فقط در فایل build.gradle تعریف کنید. برای جزئیات بیشتر، پیکربندی ساخت خود را ببینید.

ادغام اکتشافی درگیری

ابزار ادغام می تواند منطقاً هر عنصر XML را از یک مانیفست به عنصر مربوطه در مانیفست دیگر مطابقت دهد. برای جزئیات در مورد نحوه تطبیق، اولویت‌های ادغام را در بخش قبل ببینید.

اگر عنصری از مانیفست با اولویت پایین تر با هیچ عنصری در مانیفست با اولویت بالاتر مطابقت نداشته باشد، به مانیفست ادغام شده اضافه می شود. با این حال، اگر یک عنصر منطبق وجود داشته باشد، ابزار ادغام تلاش می‌کند تا همه ویژگی‌ها را از هر یک در یک عنصر ترکیب کند. اگر ابزار متوجه شود که هر دو مانیفست دارای یک ویژگی با مقادیر متفاوت هستند، تضاد ادغام رخ می دهد.

جدول 1 نتایج احتمالی را هنگامی که ابزار ادغام تلاش می کند همه ویژگی ها را در یک عنصر ترکیب کند، نشان می دهد.

جدول 1. رفتار ادغام پیش فرض برای مقادیر ویژگی

ویژگی با اولویت بالا ویژگی با اولویت پایین نتیجه ادغام ویژگی
بدون ارزش بدون ارزش بدون مقدار (از مقدار پیش فرض استفاده کنید)
ارزش B ارزش B
ارزش A بدون ارزش ارزش A
ارزش A ارزش A
ارزش B خطای تضاد - باید یک نشانگر قانون ادغام اضافه کنید.

با این حال، چند موقعیت وجود دارد که در آن ابزار ادغام برای جلوگیری از تضادهای ادغام رفتار متفاوتی دارد:

  • ویژگی های عنصر <manifest> هرگز با هم ادغام نمی شوند. فقط از ویژگی های مانیفست با بالاترین اولویت استفاده می شود.
  • ویژگی android:required در عناصر <uses-feature> و <uses-library> از ادغام OR استفاده می کند. اگر تضاد وجود داشته باشد، "true" اعمال می شود و ویژگی یا کتابخانه مورد نیاز یک مانیفست همیشه گنجانده می شود.
  • ویژگی‌های عنصر <uses-sdk> همیشه از مقدار مانیفست با اولویت بالاتر استفاده می‌کنند، مگر در شرایط زیر:
    • وقتی مانیفست با اولویت پایین‌تر دارای مقدار minSdk است که بالاتر است، خطایی رخ می‌دهد مگر اینکه قانون ادغام overrideLibrary را اعمال کنید.
    • وقتی مانیفست با اولویت پایین‌تر دارای مقدار targetSdkVersion است که کمتر است، ابزار ادغام از مقدار مانیفست با اولویت بالاتر استفاده می‌کند و همچنین هر گونه مجوز سیستم را که برای اطمینان از ادامه عملکرد صحیح کتابخانه وارد شده (برای مواردی در که نسخه بالاتر اندروید محدودیت های مجوز را افزایش داده است). برای اطلاعات بیشتر در مورد این رفتار، به بخش مربوط به مجوزهای سیستم ضمنی مراجعه کنید.
  • عنصر <intent-filter> هرگز بین مانیفست ها مطابقت داده نمی شود. هر یک به عنوان یکتا در نظر گرفته می شود و به عنصر والد مشترک در مانیفست ادغام شده اضافه می شود.

برای تمام درگیری‌های دیگر بین ویژگی‌ها، یک خطا دریافت می‌کنید و باید به ابزار ادغام آموزش دهید که چگونه آن را با افزودن یک ویژگی خاص در فایل مانیفست با اولویت بالاتر حل کند. بخش زیر را در مورد نشانگرهای قانون ادغام ببینید.

به مقادیر مشخصه پیش فرض وابسته نباشید. از آنجایی که همه ویژگی‌های منحصربه‌فرد در یک عنصر ترکیب می‌شوند، اگر مانیفست با اولویت بالاتر واقعاً به مقدار پیش‌فرض یک ویژگی بدون اعلام آن بستگی داشته باشد، ممکن است نتایج غیرمنتظره‌ای ایجاد کند. به عنوان مثال، اگر مانیفست با اولویت بالاتر ویژگی android:launchMode را اعلام نکند، از مقدار پیش‌فرض "standard" استفاده می‌کند — اما اگر مانیفست با اولویت پایین‌تر این ویژگی را با مقدار متفاوتی اعلام کند، آن مقدار به آن اعمال می‌شود. مانیفست ادغام شده، که مقدار پیش فرض را لغو می کند. شما باید به صراحت هر ویژگی را همانطور که می خواهید تعریف کنید. مقادیر پیش فرض برای هر ویژگی در مرجع مانیفست مستند شده است.

نشانگرهای قانون را ادغام کنید

نشانگر قانون ادغام یک ویژگی XML است که می‌توانید از آن برای بیان ترجیحات خود در مورد نحوه حل تعارضات ادغام یا حذف عناصر و ویژگی‌های ناخواسته استفاده کنید. شما می توانید یک نشانگر را برای کل یک عنصر یا فقط به ویژگی های خاص یک عنصر اعمال کنید.

هنگام ادغام دو فایل مانیفست، ابزار ادغام این نشانگرها را در فایل مانیفست با اولویت بالاتر جستجو می کند.

همه نشانگرها به فضای نام tools Android تعلق دارند، بنابراین باید ابتدا این فضای نام را در عنصر <manifest> اعلام کنید، همانطور که در اینجا نشان داده شده است:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp"
    xmlns:tools="http://schemas.android.com/tools">

نشانگرهای گره

برای اعمال یک قانون ادغام به کل عنصر XML (برای همه ویژگی‌های یک عنصر مانیفست معین و همه تگ‌های فرزند آن)، از ویژگی‌های زیر استفاده کنید:

tools:node="merge"
با استفاده از اکتشافی تضاد ادغام، تمام ویژگی‌های این تگ و همه عناصر تودرتو را در صورت عدم وجود تضاد، ادغام کنید. این رفتار پیش فرض برای عناصر است.

مانیفست با اولویت پایین:

<activity android:name="com.example.ActivityOne"
    android:windowSoftInputMode="stateUnchanged">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

مانیفست با اولویت بالا:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    tools:node="merge">
</activity>

نتیجه آشکار ادغام شده:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
tools:node="merge-only-attributes"
ادغام ویژگی ها فقط در این تگ. عناصر تو در تو را ادغام نکنید

مانیفست با اولویت پایین:

<activity android:name="com.example.ActivityOne"
    android:windowSoftInputMode="stateUnchanged">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

مانیفست با اولویت بالا:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    tools:node="merge-only-attributes">
</activity>

نتیجه آشکار ادغام شده:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
</activity>
tools:node="remove"
این عنصر را از مانیفست ادغام شده حذف کنید. زمانی استفاده می شود که عنصری را در مانیفست ادغام شده خود کشف کنید که به آن نیاز ندارید و توسط یک فایل مانیفست با اولویت پایین تر ارائه شده است که خارج از کنترل شما است (مانند یک کتابخانه وارد شده).

مانیفست با اولویت پایین:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="cow"
      android:value="@string/moo"/>
  <meta-data android:name="duck"
      android:value="@string/quack"/>
</activity-alias>

مانیفست با اولویت بالا:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="cow"
      tools:node="remove"/>
</activity-alias>

نتیجه آشکار ادغام شده:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="duck"
      android:value="@string/quack"/>
</activity-alias>
tools:node="removeAll"
شبیه tools:node="remove" ، اما تمام عناصر مطابق با این نوع عنصر (در همان عنصر والد) را حذف می کند.

مانیفست با اولویت پایین:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="cow"
      android:value="@string/moo"/>
  <meta-data android:name="duck"
      android:value="@string/quack"/>
</activity-alias>

مانیفست با اولویت بالا:

<activity-alias android:name="com.example.alias">
  <meta-data tools:node="removeAll"/>
</activity-alias>

نتیجه آشکار ادغام شده:

<activity-alias android:name="com.example.alias">
</activity-alias>
tools:node="replace"
عنصر با اولویت پایین را به طور کامل جایگزین کنید. یعنی اگر عنصر منطبقی در مانیفست با اولویت پایین وجود دارد، آن را نادیده بگیرید و از این عنصر دقیقاً همانطور که در این مانیفست ظاهر می شود استفاده کنید.

مانیفست با اولویت پایین:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="cow"
      android:value="@string/moo"/>
  <meta-data android:name="duck"
      android:value="@string/quack"/>
</activity-alias>

مانیفست با اولویت بالا:

<activity-alias android:name="com.example.alias"
    tools:node="replace">
  <meta-data android:name="fox"
      android:value="@string/dingeringeding"/>
</activity-alias>

نتیجه آشکار ادغام شده:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="fox"
      android:value="@string/dingeringeding"/>
</activity-alias>
tools:node="strict"
هر زمانی که این عنصر در مانیفست با اولویت پایین‌تر دقیقاً با عنصر موجود در مانیفست با اولویت بالاتر مطابقت نداشت، یک شکست ساخت ایجاد کنید (مگر اینکه توسط سایر نشانگرهای قانون ادغام حل شود). این اکتشافی تضاد ادغام را لغو می کند. به عنوان مثال، اگر مانیفست با اولویت پایین شامل یک ویژگی اضافی باشد، ساخت با شکست مواجه می شود (در حالی که رفتار پیش فرض ویژگی اضافی را به مانیفست ادغام شده اضافه می کند).

مانیفست با اولویت پایین:

<activity android:name="com.example.ActivityOne"
    android:windowSoftInputMode="stateUnchanged">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

مانیفست با اولویت بالا:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    tools:node="strict">
</activity>

این یک خطای ادغام آشکار ایجاد می کند. دو عنصر آشکار به هیچ وجه نمی توانند در حالت دقیق متفاوت باشند. برای حل این تفاوت ها باید سایر نشانگرهای قانون ادغام را اعمال کنید. (بدون tools:node="strict" ، این دو فایل می توانند بدون خطا با هم ادغام شوند، همانطور که در مثال برای tools:node="merge" نشان داده شده است.)

نشانگرهای صفت

برای اعمال قانون ادغام فقط برای ویژگی های خاص در یک تگ مانیفست، از ویژگی های زیر استفاده کنید. هر ویژگی یک یا چند نام ویژگی (از جمله فضای نام ویژگی) را می پذیرد که با کاما از هم جدا شده اند.

tools:remove=" attr, ... "
ویژگی های مشخص شده را از مانیفست ادغام شده حذف کنید. زمانی استفاده می‌شود که فایل مانیفست با اولویت پایین‌تر شامل این ویژگی‌ها باشد و می‌خواهید مطمئن شوید که آنها به مانیفست ادغام‌شده نمی‌روند.

مانیفست با اولویت پایین:

<activity android:name="com.example.ActivityOne"
    android:windowSoftInputMode="stateUnchanged">

مانیفست با اولویت بالا:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    tools:remove="android:windowSoftInputMode">

نتیجه آشکار ادغام شده:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait">
tools:replace=" attr, ... "
ویژگی های مشخص شده در مانیفست با اولویت پایین را با ویژگی های این مانیفست جایگزین کنید. به عبارت دیگر، همیشه مقادیر مانیفست با اولویت بالاتر را حفظ کنید.

مانیفست با اولویت پایین:

<activity android:name="com.example.ActivityOne"
    android:theme="@oldtheme"
    android:exported="false"
    android:windowSoftInputMode="stateUnchanged">

مانیفست با اولویت بالا:

<activity android:name="com.example.ActivityOne"
    android:theme="@newtheme"
    android:exported="true"
    android:screenOrientation="portrait"
    tools:replace="android:theme,android:exported">

نتیجه آشکار ادغام شده:

<activity android:name="com.example.ActivityOne"
    android:theme="@newtheme"
    android:exported="true"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
tools:strict=" attr, ... "
هر زمان که این ویژگی‌ها در مانیفست با اولویت پایین‌تر دقیقاً با ویژگی‌های مانیفست با اولویت بالاتر مطابقت ندارند، یک شکست ساخت ایجاد کنید. این رفتار پیش‌فرض برای همه ویژگی‌ها است، به جز مواردی که رفتارهای خاصی دارند که در اکتشافی تضاد ادغام توضیح داده شده است.

مانیفست با اولویت پایین:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="landscape">
</activity>

مانیفست با اولویت بالا:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    tools:strict="android:screenOrientation">
</activity>

این یک خطای ادغام آشکار ایجاد می کند. برای حل تعارض باید سایر نشانگرهای قانون ادغام را اعمال کنید. این رفتار پیش‌فرض است، بنابراین همان نتیجه با افزودن صریح tools:strict="screenOrientation" .

همانطور که در مثال زیر نشان داده شده است، می توانید چندین نشانگر را به یک عنصر اعمال کنید:

مانیفست با اولویت پایین:

<activity android:name="com.example.ActivityOne"
    android:theme="@oldtheme"
    android:exported="false"
    android:allowTaskReparenting="true"
    android:windowSoftInputMode="stateUnchanged">

مانیفست با اولویت بالا:

<activity android:name="com.example.ActivityOne"
    android:theme="@newtheme"
    android:exported="true"
    android:screenOrientation="portrait"
    tools:replace="android:theme,android:exported"
    tools:remove="android:windowSoftInputMode">

نتیجه آشکار ادغام شده:

<activity android:name="com.example.ActivityOne"
    android:theme="@newtheme"
    android:exported="true"
    android:allowTaskReparenting="true"
    android:screenOrientation="portrait">

انتخابگر نشانگر

اگر می‌خواهید نشانگرهای قانون ادغام را فقط برای یک کتابخانه وارداتی خاص اعمال کنید، ویژگی tools:selector با نام بسته کتابخانه اضافه کنید.

برای مثال، با مانیفست زیر، قانون ادغام remove فقط زمانی اعمال می شود که فایل مانیفست با اولویت پایین از کتابخانه com.example.lib1 باشد:

<permission android:name="permissionOne"
    tools:node="remove"
    tools:selector="com.example.lib1">

اگر مانیفست با اولویت پایین از هر منبع دیگری باشد، قانون ادغام remove نادیده گرفته می شود.

توجه: اگر از این مورد با یکی از نشانگرهای مشخصه استفاده می کنید، برای تمام ویژگی های مشخص شده در نشانگر اعمال می شود.

برای کتابخانه های وارد شده، <uses-sdk> را لغو کنید

به طور پیش فرض، هنگام وارد کردن کتابخانه ای با مقدار minSdk که بالاتر از فایل مانیفست اصلی است، خطایی رخ می دهد و کتابخانه نمی تواند وارد شود.

برای اینکه ابزار ادغام این تضاد را نادیده بگیرد و کتابخانه را وارد کند و در عین حال مقدار minSdk کمتری را در برنامه شما حفظ کند، ویژگی overrideLibrary را به تگ <uses-sdk> اضافه کنید. مقدار مشخصه می تواند یک یا چند نام بسته کتابخانه باشد (با کاما از هم جدا شده اند)، که نشان دهنده کتابخانه هایی است که می توانند minSdk مانیفست اصلی را لغو کنند.

به عنوان مثال، اگر مانیفست اصلی برنامه شما overrideLibrary به این صورت اعمال کند:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.app"
          xmlns:tools="http://schemas.android.com/tools">
  <uses-sdk tools:overrideLibrary="com.example.lib1, com.example.lib2"/>
...

سپس مانیفست زیر را می توان بدون خطا در رابطه با تگ <uses-sdk> ادغام کرد و مانیفست ادغام شده minSdk="2" از مانیفست برنامه نگه می دارد.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.lib1">
   <uses-sdk android:minSdk="4" />
...

مجوزهای سیستمی ضمنی

برخی از APIهای Android که زمانی به صورت رایگان توسط برنامه‌ها در دسترس بودند، توسط مجوزهای سیستم در نسخه‌های اخیر Android محدود شده‌اند.

برای جلوگیری از شکستن برنامه‌هایی که انتظار دسترسی به این APIها را دارند، نسخه‌های اخیر Android به برنامه‌ها اجازه می‌دهد بدون اجازه به آن APIها دسترسی داشته باشند، اگر targetSdkVersion روی مقداری کمتر از نسخه‌ای که محدودیت اضافه شده تنظیم شده باشد. این رفتار به برنامه یک مجوز ضمنی برای اجازه دسترسی به APIها می دهد. مانیفست های ادغام شده ای که مقادیر متفاوتی برای targetSdkVersion دارند می توانند تحت تأثیر قرار گیرند.

اگر فایل مانیفست با اولویت پایین‌تر مقدار کمتری برای targetSdkVersion داشته باشد که یک مجوز ضمنی برای آن فراهم می‌کند، و مانیفست با اولویت بالاتر همان مجوز ضمنی را نداشته باشد (زیرا targetSdkVersion آن برابر یا بالاتر از نسخه‌ای است که در آن محدودیت وجود دارد. اضافه شد)، سپس ابزار ادغام به صراحت مجوز سیستم را به مانیفست ادغام شده اضافه می کند.

برای مثال، اگر برنامه شما targetSdkVersion را روی 4 یا بالاتر تنظیم کند و کتابخانه ای با targetSdkVersion روی 3 یا پایین تر وارد کند، ابزار ادغام مجوز WRITE_EXTERNAL_STORAGE را به مانیفست ادغام شده اضافه می کند.

جدول 2 تمام مجوزهای ممکنی را که می توان به مانیفست ادغام شده شما اضافه کرد فهرست می کند:

جدول 2. فهرست مجوزهایی که ابزار ادغام ممکن است به مانیفست ادغام شده اضافه کند

مانیفست با اولویت پایین‌تر اعلام می‌کند مجوزها به مانیفست ادغام شده اضافه شدند
targetSdkVersion 3 یا کمتر است WRITE_EXTERNAL_STORAGE ، READ_PHONE_STATE
targetSdkVersion 15 یا کمتر است و از READ_CONTACTS استفاده می کند READ_CALL_LOG
targetSdkVersion 15 یا کمتر است و از WRITE_CONTACTS استفاده می کند WRITE_CALL_LOG

مانیفست ادغام شده را بررسی کنید و تضادها را پیدا کنید

حتی قبل از اینکه برنامه خود را بسازید، می توانید پیش نمایشی از ظاهر مانیفست ادغام شده خود را مشاهده کنید. برای مشاهده پیش نمایش، موارد زیر را انجام دهید:

  1. در Android Studio، فایل AndroidManifest.xml خود را باز کنید.
  2. روی تب Manifest Merged در پایین ویرایشگر کلیک کنید.

نمای Manifest ادغام شده نتایج مانیفست ادغام شده را در سمت چپ و اطلاعات مربوط به هر فایل مانیفست ادغام شده در سمت راست را همانطور که در شکل 2 نشان داده شده است نشان می دهد.

عناصری که از فایل های مانیفست با اولویت پایین ادغام شده اند با رنگ های مختلف در سمت چپ برجسته می شوند. کلید هر رنگ در Manifest Sources مشخص شده است.

شکل 2. نمای Manifest Merged.

فایل‌های مانیفست که بخشی از ساخت بودند، اما عناصر یا ویژگی‌هایی را ارائه نکردند، در زیر فایل‌های دیگر مانیفست فهرست شده‌اند.

برای مشاهده اطلاعات مربوط به جایی که یک عنصر از کجا آمده است، روی آن در پنجره سمت چپ کلیک کنید و جزئیات در زیر ثبت ادغام ظاهر می شود.

در صورت بروز هرگونه تداخل، در زیر خطاهای ادغام با توصیه ای برای نحوه حل تعارض با استفاده از نشانگرهای قانون ادغام ظاهر می شود.

خطاها نیز در پنجره گزارش رویداد چاپ می شوند. برای مشاهده آنها، View > Tool Windows > Event Log را انتخاب کنید.

برای مشاهده یک گزارش کامل از درخت تصمیم ادغام، می توانید فایل گزارش را در پوشه build/outputs/logs/ ماژول خود با نام manifest-merger- buildVariant -report.txt پیدا کنید.

سیاست های ادغام

ابزار ادغام مانیفست به طور منطقی می تواند هر عنصر XML را از یک فایل مانیفست با عنصر مربوطه در فایل دیگر مطابقت دهد. ادغام با هر عنصر با استفاده از یک کلید مطابقت دارد، یا یک مقدار مشخصه منحصر به فرد (مانند android:name ) یا منحصر به فرد بودن طبیعی خود برچسب (به عنوان مثال، فقط یک عنصر <supports-screen> می تواند وجود داشته باشد).

اگر دو مانیفست عنصر XML یکسانی داشته باشند، ابزار با استفاده از یکی از سه خط مشی ادغام، دو عنصر را با هم ادغام می کند:

ادغام
همه ویژگی‌های غیر متناقض را در یک برچسب ترکیب کنید و عناصر فرزند را طبق خط‌مشی ادغام مربوطه ادغام کنید. اگر هر یک از ویژگی ها با یکدیگر تضاد دارند، آنها را با نشانگرهای قانون ادغام ادغام کنید.
فقط کودکان را ادغام کنید
ویژگی ها را ترکیب یا ادغام نکنید (فقط ویژگی های ارائه شده توسط فایل مانیفست با بالاترین اولویت را حفظ کنید) و عناصر فرزند را مطابق خط مشی ادغام آنها ادغام نکنید.
نگه دارید
عنصر را همانطور که هست بگذارید و آن را به عنصر والد مشترک در فایل ادغام شده اضافه کنید. این تنها زمانی استفاده می‌شود که وجود چندین اعلان از یک عنصر قابل قبول باشد.

جدول 3 هر نوع عنصر، نوع خط مشی ادغام مورد استفاده، و کلید مورد استفاده برای تعیین تطابق عنصر بین دو مانیفست را فهرست می کند:

جدول 3. سیاست‌های ادغام عناصر و کلیدهای مطابقت را نشان دهید

عنصر سیاست ادغام کلید مطابقت
<action> ادغام ویژگی android:name
<activity> ادغام ویژگی android:name
<application> ادغام در هر <manifest> فقط یک مورد وجود دارد.
<category> ادغام ویژگی android:name
<data> ادغام در هر <intent-filter> فقط یک مورد وجود دارد.
<grant-uri-permission> ادغام در هر <provider> فقط یک مورد وجود دارد.
<instrumentation> ادغام ویژگی android:name
<intent-filter> نگه دارید عدم تطابق؛ چندین اعلان در عنصر والد مجاز است.
<manifest> فقط کودکان را ادغام کنید در هر فایل فقط یک مورد وجود دارد.
<meta-data> ادغام ویژگی android:name
<path-permission> ادغام در هر <provider> فقط یک مورد وجود دارد.
<permission-group> ادغام ویژگی android:name
<permission> ادغام ویژگی android:name
<permission-tree> ادغام ویژگی android:name
<provider> ادغام ویژگی android:name
<receiver> ادغام ویژگی android:name
<screen> ادغام ویژگی android:screenSize
<service> ادغام ویژگی android:name
<supports-gl-texture> ادغام ویژگی android:name
<supports-screen> ادغام در هر <manifest> فقط یک مورد وجود دارد.
<uses-configuration> ادغام در هر <manifest> فقط یک مورد وجود دارد.
<uses-feature> ادغام ویژگی android:name (اگر وجود ندارد، ویژگی android:glEsVersion )
<uses-library> ادغام ویژگی android:name
<uses-permission> ادغام ویژگی android:name
<uses-sdk> ادغام در هر <manifest> فقط یک مورد وجود دارد.
عناصر سفارشی ادغام عدم تطابق؛ اینها برای ابزار ادغام ناشناخته هستند و همیشه در مانیفست ادغام شده گنجانده می شوند.

متغیرهای ساخت را به مانیفست تزریق کنید

اگر می‌خواهید متغیرهایی را در فایل AndroidManifest.xml خود وارد کنید که در فایل build.gradle شما تعریف شده‌اند، می‌توانید این کار را با ویژگی manifestPlaceholders انجام دهید. این ویژگی نقشه ای از جفت های کلید-مقدار را می گیرد، همانطور که در اینجا نشان داده شده است:

شیار

android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
    }
    ...
}

کاتلین

android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
    }
    ...
}

سپس می‌توانید یکی از نگه‌دارنده‌ها را به عنوان مقدار مشخصه در فایل مانیفست قرار دهید:

<intent-filter ... >
    <data android:scheme="https" android:host="${hostName}" ... />
    ...
</intent-filter>

به‌طور پیش‌فرض، ابزارهای ساخت، شناسه برنامه برنامه شما را در جای‌بانی ${applicationId} نیز ارائه می‌کنند. مقدار همیشه با شناسه برنامه نهایی برای ساخت فعلی، از جمله تغییرات بر اساس انواع ساخت، مطابقت دارد. این زمانی مفید است که می‌خواهید از یک فضای نام منحصربه‌فرد برای شناسه‌هایی مانند یک اقدام قصد استفاده کنید، حتی بین انواع ساخت خود.

برای مثال، اگر فایل build.gradle شما به این شکل است:

شیار

android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    flavorDimensions "type"
    productFlavors {
        free {
            applicationIdSuffix ".free"
            dimension "type"
        }
        pro {
            applicationIdSuffix ".pro"
            dimension "type"
        }
    }
}

کاتلین

android {
    defaultConfig {
        applicationId = "com.example.myapp"
    }
    flavorDimensions += "type"
    productFlavors {
        create("free") {
            applicationIdSuffix = ".free"
            dimension = "type"
        }
        create("pro") {
            applicationIdSuffix = ".pro"
            dimension = "type"
        }
    }
}

سپس می توانید شناسه برنامه را به این صورت در مانیفست خود وارد کنید:

<intent-filter ... >
    <action android:name="${applicationId}.TRANSMOGRIFY" />
    ...
</intent-filter>

و نتیجه آشکار هنگامی که طعم محصول "رایگان" را ایجاد می کنید این است:

<intent-filter ... >
   <action android:name="com.example.myapp.free.TRANSMOGRIFY" />
    ...
</intent-filter>

برای اطلاعات بیشتر، تنظیم شناسه برنامه را بخوانید.