จัดการไฟล์ Manifest

หน้านี้อธิบายวิธีการทำงานของการรวมไฟล์ Manifest และวิธีนำการผสานรวมไปใช้ ค่ากำหนดเพื่อ แก้ไขความขัดแย้งในการรวม สำหรับข้อมูลเบื้องต้นเกี่ยวกับแอป ไฟล์ Manifest โปรดดู ภาพรวมไฟล์ Manifest ของแอป

รวมไฟล์ Manifest หลายไฟล์

ไฟล์ APK หรือ Android App Bundle จะมีได้เพียงไฟล์เดียว AndroidManifest.xml แต่โปรเจ็กต์ Android Studio ของคุณอาจมี ไฟล์ Manifest หลายไฟล์ที่ได้จากชุดแหล่งที่มาหลัก เวอร์ชันของบิลด์ และการนำเข้า ห้องสมุด เมื่อสร้างแอป บิลด์ Gradle จะรวมเข้าด้วยกัน ไฟล์ Manifest ทั้งหมดไว้ในไฟล์ Manifest ไฟล์เดียวที่มีการจัดแพ็กเกจ ในแอปของคุณ

เครื่องมือผสานไฟล์ Manifest จะรวมองค์ประกอบ XML ทั้งหมดจากแต่ละไฟล์โดยทำตามลิงก์ต่อไปนี้ ศึกษาวิธีการผสานและทำตามค่ากำหนดการผสานที่คุณได้กำหนดไว้ ด้วยแอตทริบิวต์ XML พิเศษ

เคล็ดลับ: ใช้ไฟล์ Manifest ที่ผสานรวม อีกครั้ง ซึ่งอธิบายไว้ในส่วนต่อไปนี้ เพื่อดูตัวอย่างผลลัพธ์ของไฟล์ Manifest ที่ผสานรวมและค้นหาความขัดแย้ง

รวมลำดับความสำคัญ

เครื่องมือผสานจะรวมไฟล์ Manifest ทั้งหมดไว้ในไฟล์เดียว ตามลำดับ ตามลำดับความสำคัญของไฟล์ Manifest แต่ละไฟล์ ตัวอย่างเช่น หากคุณมี ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำสุด 3 ไฟล์จะรวมเข้าด้วยกันเป็น ไฟล์ Manifest ที่มีลำดับความสำคัญสูงสุดลำดับถัดไป จากนั้นจะรวมเข้ากับไฟล์ Manifest ที่มีลำดับความสำคัญสูงสุด ตามที่แสดงในรูปที่ 1

รูปที่ 1 ขั้นตอนการรวมไฟล์ Manifest ทั้ง 3 รายการ ไฟล์ที่มีลำดับความสำคัญต่ำสุด มีความสำคัญสูงสุด

ไฟล์ Manifest มี 3 ประเภทพื้นฐาน 3 ประเภทที่สามารถรวมไว้ในไฟล์แต่ละประเภท อื่นๆ และลำดับความสำคัญของการรวมมีดังต่อไปนี้ (ลำดับความสำคัญสูงสุดก่อน)

  1. ไฟล์ Manifest สำหรับ สร้างตัวแปร

    หากคุณมีชุดแหล่งที่มาหลายชุดสำหรับตัวแปร ตัวแปร ลำดับความสำคัญของไฟล์ Manifest มีดังนี้

    • สร้างไฟล์ Manifest ของตัวแปร (เช่น src/demoDebug/)
    • ไฟล์ Manifest ประเภทบิลด์ (เช่น src/debug/)
    • ไฟล์ Manifest ของเวอร์ชันผลิตภัณฑ์ (เช่น src/demo/)

      หากคุณใช้มิติข้อมูลเวอร์ชัน ลำดับความสำคัญของไฟล์ Manifest จะสอดคล้องกับลำดับที่มิติข้อมูลแต่ละรายการแสดงอยู่ใน พร็อพเพอร์ตี้ flavorDimensions (อันดับแรกคือลำดับความสำคัญสูงสุด)

  2. ไฟล์ Manifest หลักสำหรับโมดูลแอป
  3. ไฟล์ Manifest จากไลบรารีที่รวมไว้

    หากคุณมีไลบรารีหลายรายการ ลำดับความสำคัญของไฟล์ Manifest ของไลบรารีแต่ละรายการจะตรงกัน ลำดับที่ปรากฏใน Gradle บล็อก dependencies

ตัวอย่างเช่น ไฟล์ Manifest ของไลบรารีจะรวมเข้าเป็นไฟล์ Manifest หลัก จากนั้นจะรวมไว้ในไฟล์ Manifest หลัก ไฟล์ Manifest จะรวมอยู่ในไฟล์ Manifest ของรูปแบบบิลด์ โปรดทราบว่าข้อมูลเหล่านี้คือข้อมูลเดียวกัน รวมลำดับความสำคัญสำหรับชุดแหล่งที่มาทั้งหมด ตามที่อธิบายใน สร้างด้วยชุดแหล่งที่มา

สำคัญ: สร้างการกำหนดค่าจาก ไฟล์ build.gradle จะลบล้างแอตทริบิวต์ที่เกี่ยวข้องใน ไฟล์ Manifest ที่ผสานรวม ตัวอย่างเช่น minSdk จากbuild.gradle หรือ ไฟล์ build.gradle.kts จะลบล้างแอตทริบิวต์ที่ตรงกันใน <uses-sdk> ของไฟล์ Manifest เพื่อป้องกันความสับสน <uses-sdk> และกำหนดพร็อพเพอร์ตี้เหล่านี้ใน build.gradle ดูรายละเอียดเพิ่มเติมได้ที่ กำหนดค่าบิลด์

ผสานกระบวนการแสดงความขัดแย้ง

เครื่องมือผสานสามารถจับคู่องค์ประกอบ XML ทุกรายการอย่างสมเหตุสมผลจากไฟล์ Manifest หนึ่งกับ ที่เกี่ยวข้องในไฟล์ Manifest อื่น สำหรับรายละเอียดเกี่ยวกับวิธีจับคู่ โปรดดูลำดับความสำคัญในการรวมในส่วนก่อนหน้านี้

หากองค์ประกอบจากไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่าไม่ตรงกับองค์ประกอบใดๆ ใน ไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า จะถูกเพิ่มลงในไฟล์ Manifest ที่ผสานรวมแล้ว อย่างไรก็ตาม หากมีองค์ประกอบที่ตรงกัน เครื่องมือผสานจะพยายามรวม จากแต่ละแอตทริบิวต์ลงในองค์ประกอบเดียวกัน หากเครื่องมือพบว่า ไฟล์ Manifest มีแอตทริบิวต์เดียวกันโดยมีค่าต่างกัน และมีการผสาน เกิดความขัดแย้งขึ้น

ตาราง 1 แสดงผลลัพธ์ที่เป็นไปได้เมื่อเครื่องมือผสานพยายามรวม ทั้งหมดไว้ในองค์ประกอบเดียวกัน

ตาราง 1 ลักษณะการรวมเริ่มต้นสำหรับแอตทริบิวต์ ค่า

แอตทริบิวต์ที่มีลำดับความสำคัญสูง แอตทริบิวต์ที่มีลำดับความสำคัญต่ำ ผลลัพธ์ที่ผสานรวมของแอตทริบิวต์
ไม่มีคุณค่า ไม่มีคุณค่า ไม่มีค่า (ใช้ค่าเริ่มต้น)
ค่า B ค่า B
ค่า A ไม่มีคุณค่า ค่า A
ค่า A ค่า A
ค่า B ข้อผิดพลาดเกี่ยวกับความขัดแย้ง คุณต้องเพิ่ม เครื่องหมายกฎการผสาน

อย่างไรก็ตาม มีบางสถานการณ์ที่เครื่องมือผสานรวมจะทำงานต่างออกไป เพื่อหลีกเลี่ยงความขัดแย้งในการรวม

  • แอตทริบิวต์ในองค์ประกอบ <manifest> จะไม่ผสานเข้าด้วยกัน ใช้เฉพาะแอตทริบิวต์จากไฟล์ Manifest ที่มีลำดับความสำคัญสูงสุดเท่านั้น
  • แอตทริบิวต์ android:required ใน <uses-feature> และ องค์ประกอบ <uses-library> ใช้ การผสาน OR หากมีการทับซ้อนกัน "true" จะเป็น และมีฟีเจอร์หรือไลบรารีที่ไฟล์ Manifest 1 ไฟล์จำเป็นต้องใช้เสมอ
  • แอตทริบิวต์ใน องค์ประกอบ <uses-sdk> จะใช้ค่าจาก ไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า ยกเว้นในสถานการณ์ต่อไปนี้
    • เมื่อไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่ามีค่า minSdk สูงกว่า จะเกิดข้อผิดพลาดขึ้นได้ เว้นแต่คุณจะ ใช้ กฎการรวม overrideLibrary รายการ
    • เมื่อไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่ามี targetSdkVersion ค่าที่ต่ำกว่า เครื่องมือผสานจะใช้ค่า จากไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า และ ซึ่งจำเป็นต่อการทำให้ไลบรารีที่นำเข้ายังคง ทำงานได้อย่างถูกต้อง (ในกรณีที่ Android เวอร์ชันสูงกว่ามี การจำกัดสิทธิ์ที่เพิ่มขึ้น) สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ พฤติกรรม โปรดดูส่วน เกี่ยวกับ implicit System สิทธิ์
  • องค์ประกอบ <intent-filter> จะไม่มีการจับคู่ระหว่าง ไฟล์ Manifest แต่ละรูปแบบจะถือว่าไม่ซ้ำกันและ ลงในองค์ประกอบระดับบนสุดทั่วไปในไฟล์ Manifest ที่ผสานรวมแล้ว

สําหรับความขัดแย้งอื่นๆ ทั้งหมดระหว่างแอตทริบิวต์ คุณจะได้รับข้อผิดพลาดและคุณต้อง ให้เครื่องมือผสานการแก้ไขโดยเพิ่มแอตทริบิวต์พิเศษใน ไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า โปรดดูส่วนต่อไปนี้เกี่ยวกับ เครื่องหมายกฎการผสาน

อย่าพึ่งพาค่าแอตทริบิวต์เริ่มต้น เพราะทั้งหมด แอตทริบิวต์ที่ไม่ซ้ำกันจะรวมกันเป็น องค์ประกอบเดียวกัน ซึ่งอาจทำให้ ผลลัพธ์ที่ไม่คาดคิดหากไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่าจะขึ้นอยู่กับ ค่าเริ่มต้นของแอตทริบิวต์โดยไม่ประกาศ ตัวอย่างเช่น ถ้ายิ่ง ไฟล์ Manifest ที่มีลำดับความสำคัญไม่ประกาศ android:launchMode แอตทริบิวต์ดังกล่าวจะใช้ค่าเริ่มต้น "standard" แต่หากแอตทริบิวต์ ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่าจะประกาศแอตทริบิวต์นี้ด้วยค่าอื่น ไปใช้กับไฟล์ Manifest ที่ผสานรวมแล้ว ซึ่งจะแทนที่ค่าเริ่มต้น คุณ ควรกำหนดแอตทริบิวต์แต่ละรายการอย่างชัดแจ้งตามที่ต้องการ ค่าเริ่มต้น สำหรับแต่ละแอตทริบิวต์ที่ระบุไว้ใน ข้อมูลอ้างอิง

รวมเครื่องหมายกฎ

เครื่องหมายกฎการผสานเป็นแอตทริบิวต์ XML ที่ใช้เพื่อแสดงค่ากำหนดได้ เกี่ยวกับวิธีแก้ไขความขัดแย้งในการรวมหรือนำองค์ประกอบและแอตทริบิวต์ที่ไม่ต้องการออก คุณสามารถใช้เครื่องหมายกับทั้งองค์ประกอบหรือกับเฉพาะบางองค์ประกอบ ในองค์ประกอบ

เมื่อผสานไฟล์ Manifest 2 ไฟล์ เครื่องมือผสานจะมองหาเครื่องหมายเหล่านี้ใน ไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า

เครื่องหมายทั้งหมดเป็นของเนมสเปซ Android tools คุณจึงต้องประกาศก่อน Namespace นี้ในองค์ประกอบ <manifest> ดังที่แสดงที่นี่

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

เครื่องหมายโหนด

หากต้องการใช้กฎการผสานกับองค์ประกอบ XML ทั้งหมด (กับแอตทริบิวต์ทั้งหมดใน เอลิเมนต์ไฟล์ Manifest และแท็กย่อยทั้งหมด) ให้ใช้รายการต่อไปนี้ ดังนี้

tools:node="merge"
ผสานแอตทริบิวต์ทั้งหมดในแท็กนี้และองค์ประกอบที่ฝังทั้งหมดเมื่อมี ไม่มีความขัดแย้งโดยใช้การรวม การประเมินความขัดแย้ง ซึ่งเป็นลักษณะการทำงานเริ่มต้นขององค์ประกอบ

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

<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"
รวมแอตทริบิวต์ในแท็กนี้เท่านั้น อย่าผสานองค์ประกอบที่ซ้อนอยู่

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
</activity>
tools:node="remove"
นำองค์ประกอบนี้ออกจากไฟล์ Manifest ที่ผสานรวมแล้ว ใช้เมื่อ คุณพบองค์ประกอบในไฟล์ Manifest ที่ผสานรวมกันซึ่งไม่จำเป็นต้องใช้ มาจากไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่าซึ่งคุณควบคุมไม่ได้ (เช่น ไลบรารีที่นำเข้า)

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="duck"
      android:value="@string/quack"/>
</activity-alias>
tools:node="removeAll"
คล้ายกับ tools:node="remove" แต่จะนำทั้งหมดออก องค์ประกอบที่ตรงกับประเภทองค์ประกอบนี้ (ภายในองค์ประกอบระดับบนเดียวกัน)

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

<activity-alias android:name="com.example.alias">
</activity-alias>
tools:node="replace"
แทนที่องค์ประกอบที่มีลำดับความสำคัญต่ำกว่าทั้งหมด กล่าวคือ หากมี เป็นองค์ประกอบที่ตรงกันในไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่า ไม่ต้องสนใจและใช้ องค์ประกอบนี้ตรงตามที่ปรากฏในไฟล์ Manifest นี้

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="fox"
      android:value="@string/dingeringeding"/>
</activity-alias>
tools:node="strict"
สร้างความล้มเหลวของบิลด์ทุกครั้งที่องค์ประกอบนี้ในลำดับความสำคัญต่ำกว่า ไฟล์ Manifest ไม่ตรงกันทุกประการกับองค์ประกอบในไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า (เว้นแต่ แก้ไขโดยเครื่องหมายของกฎการผสานอื่น) ซึ่งจะลบล้างการเรียนรู้เกี่ยวกับความขัดแย้งแบบผสาน สำหรับ ตัวอย่างเช่น หากไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่ามีแอตทริบิวต์เพิ่มเติม บิลด์ล้มเหลว (ในขณะที่การทำงานเริ่มต้นจะเพิ่มแอตทริบิวต์เพิ่มเติมลงใน ไฟล์ Manifest ที่ผสานรวมแล้ว)

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

การดำเนินการนี้จะสร้างข้อผิดพลาดในการรวมไฟล์ Manifest องค์ประกอบไฟล์ Manifest 2 รายการ ไม่แตกต่างกันเลยในโหมดเข้มงวด คุณต้องใช้เครื่องหมายกฎการผสานอื่นๆ เพื่อแก้ไขความแตกต่างเหล่านี้ (เมื่อไม่มี tools:node="strict" 2 ไฟล์สามารถรวมเข้าด้วยกันโดยไม่มีข้อผิดพลาด ดังที่แสดงในตัวอย่าง tools:node="merge")

ตัวทำเครื่องหมายแอตทริบิวต์

หากต้องการใช้กฎการผสานกับแอตทริบิวต์บางรายการเท่านั้นใน ให้ใช้ แอตทริบิวต์แต่ละรายการยอมรับชื่อแอตทริบิวต์อย่างน้อย 1 ชื่อ (รวมถึงแอตทริบิวต์ เนมสเปซของแอตทริบิวต์) แล้วคั่นด้วยเครื่องหมายจุลภาค

tools:remove="attr, ..."
นำแอตทริบิวต์ที่ระบุออกจากไฟล์ Manifest ที่ผสานรวมแล้ว ใช้เมื่อไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่ามีสิ่งเหล่านี้ และไม่ต้องการให้รวมแอตทริบิวต์เหล่านั้นเข้าไว้ด้วยกัน ไฟล์ Manifest

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait">
tools:replace="attr, ..."
แทนที่แอตทริบิวต์ที่ระบุในไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่าด้วย ที่มาจากไฟล์ Manifest นี้ กล่าวคือ ให้เก็บ ค่าของไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

<activity android:name="com.example.ActivityOne"
    android:theme="@newtheme"
    android:exported="true"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
tools:strict="attr, ..."
สร้างความล้มเหลวของบิลด์ทุกครั้งที่แอตทริบิวต์เหล่านี้ใน ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่าไม่ตรงทุกประการกับแอตทริบิวต์ในลำดับความสำคัญสูงกว่า ไฟล์ Manifest นี่คือลักษณะการทำงานเริ่มต้นของแอตทริบิวต์ทั้งหมด ยกเว้น ผู้ที่มีพฤติกรรมพิเศษตามที่อธิบายไว้ในการประเมินความขัดแย้งในแผนการรับมือ

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

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

การดำเนินการนี้จะสร้างข้อผิดพลาดในการรวมไฟล์ Manifest คุณต้องใช้กฎการรวมอื่นๆ ทำเครื่องหมายเพื่อแก้ไขข้อขัดแย้ง นี่คือลักษณะการทำงานเริ่มต้น ผลลัพธ์เดียวกันจะเกิดขึ้นเมื่อมีการเพิ่ม tools:strict="screenOrientation"

คุณยังสามารถใช้ตัวทำเครื่องหมายหลายตัวกับองค์ประกอบเดียว ดังที่ปรากฏในตัวอย่างต่อไปนี้:

ไฟล์ Manifest ที่มีลำดับความสำคัญต่ำ:

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

ไฟล์ Manifest ที่มีลำดับความสำคัญสูง:

<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">

ผลลัพธ์ของไฟล์ Manifest ที่ผสานรวม:

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

ตัวเลือกเครื่องหมาย

ถ้าคุณต้องการใช้เครื่องหมายกฎการผสานกับ ไลบรารีที่นำเข้า ให้เพิ่มแอตทริบิวต์ tools:selector ด้วย ชื่อแพ็กเกจห้องสมุด

ตัวอย่างเช่น สำหรับไฟล์ Manifest ต่อไปนี้ remove กฎการผสานจะใช้ได้ก็ต่อเมื่อไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่ามาจาก ไลบรารีของ com.example.lib1:

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

หากไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่ามาจากแหล่งที่มาอื่น กฎการผสาน remove รายการไม่มีผลใดๆ

หมายเหตุ: หากคุณใช้สิ่งนี้กับหนึ่งในเครื่องหมายแอตทริบิวต์ ก็จะมีผลกับแอตทริบิวต์ทั้งหมดที่ระบุไว้ในเครื่องหมายดังกล่าว

ลบล้าง <uses-sdk> สำหรับไลบรารีที่นำเข้า

โดยค่าเริ่มต้น เมื่อนำเข้าไลบรารีที่มีค่า minSdk ที่สูงกว่าไฟล์ Manifest หลัก จะเกิดข้อผิดพลาดขึ้น ไม่สามารถนำเข้าไลบรารี

หากต้องการให้เครื่องมือผสานไม่ประมวลผลความขัดแย้งนี้และ นำเข้าไลบรารีขณะที่คง minSdk ที่ต่ำกว่าของแอปไว้ ให้เพิ่มแอตทริบิวต์ overrideLibrary ลงในแท็ก <uses-sdk> ค่าแอตทริบิวต์อาจเป็นชื่อแพ็กเกจไลบรารีอย่างน้อย 1 ชื่อ (คั่นด้วยเครื่องหมายจุลภาค) ซึ่งแสดงไลบรารีที่สามารถแทนที่แท็กหลัก minSdk ของไฟล์ Manifest

เช่น หากไฟล์ Manifest หลักของแอปใช้ 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"/>
...

คุณจะสามารถรวมไฟล์ Manifest ต่อไปนี้โดยไม่มีข้อผิดพลาดเกี่ยวกับ แท็ก <uses-sdk> และไฟล์ Manifest ที่ผสานรวมจะเก็บ minSdk="2" จากไฟล์ Manifest ของแอป

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

สิทธิ์ของระบบโดยนัย

Android API บางรายการที่ครั้งหนึ่งแอปเคยเข้าถึงได้อย่างอิสระได้กลายเป็น ถูกจำกัดโดยสิทธิ์ของระบบใน Android เวอร์ชันล่าสุด

เพื่อหลีกเลี่ยงการทำให้แอปที่คาดว่ามีการเข้าถึงฟีเจอร์เหล่านี้ใช้งานไม่ได้ API ซึ่งเป็นเวอร์ชันล่าสุดของ Android ช่วยให้แอปเข้าถึง API เหล่านั้นได้ต่อไป หากตั้งค่า targetSdkVersion เป็นค่าที่ต่ำกว่าโดยไม่ได้รับอนุญาต เวอร์ชันที่มีการเพิ่มข้อจำกัด ลักษณะการทำงานนี้ จะให้สิทธิ์โดยปริยายแก่แอปเพื่ออนุญาตการเข้าถึง API ผสาน ที่มีค่าแตกต่างกันสำหรับ targetSdkVersion อาจได้รับผลกระทบ

หากไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่ามีค่าต่ำกว่าสำหรับ targetSdkVersion ที่ให้สิทธิ์โดยปริยาย และไฟล์ Manifest ที่มีลำดับความสำคัญสูงกว่า ไม่ได้มีนัยเดียวกัน (เนื่องจาก targetSdkVersion มีค่าเท่ากับหรือสูงกว่า เวอร์ชันที่มีการเพิ่มข้อจำกัด) เครื่องมือผสาน เพิ่มสิทธิ์ของระบบในไฟล์ Manifest ที่ผสานรวมอย่างชัดเจน

ตัวอย่างเช่น หากแอปตั้งค่า targetSdkVersion เป็น 4 ขึ้นไป และนำเข้า ไลบรารีที่มี targetSdkVersion ตั้งไว้ที่ 3 หรือต่ำกว่า เครื่องมือผสานจะเพิ่มค่า WRITE_EXTERNAL_STORAGE สิทธิ์ในไฟล์ Manifest ที่ผสานรวมแล้ว

ตาราง 2 แสดงรายการสิทธิ์ที่เป็นไปได้ทั้งหมด ที่สามารถเพิ่มลงในไฟล์ Manifest ที่ผสานรวมแล้ว

ตาราง 2 รายการสิทธิ์ของเครื่องมือผสาน อาจเพิ่มลงในไฟล์ Manifest ที่ผสานรวมแล้ว

การประกาศไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่า เพิ่มสิทธิ์ในไฟล์ Manifest ที่ผสานรวมแล้ว
targetSdkVersion ไม่เกิน 3 WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
targetSdkVersion อายุไม่เกิน 15 ปีและใช้ READ_CONTACTS READ_CALL_LOG
targetSdkVersion อายุไม่เกิน 15 ปีและใช้ WRITE_CONTACTS WRITE_CALL_LOG

ตรวจสอบไฟล์ Manifest ที่ผสานและค้นหาความขัดแย้ง

แม้ก่อนที่จะสร้างแอป คุณสามารถดูตัวอย่างรายการที่ผสาน ไฟล์ Manifest มีลักษณะอย่างไร หากต้องการดูตัวอย่าง ให้ทำตามขั้นตอนต่อไปนี้

  1. เปิดไฟล์ AndroidManifest.xml ใน Android Studio
  2. คลิกแท็บไฟล์ Manifest ที่ผสานรวมที่ด้านล่างของตัวแก้ไข

มุมมองไฟล์ Manifest ที่ผสานรวมจะแสดงผลลัพธ์ของไฟล์ Manifest ที่ผสานรวมทางด้านซ้าย และข้อมูลเกี่ยวกับไฟล์ Manifest ที่ผสานรวมแต่ละไฟล์ทางด้านขวา ดังที่แสดงใน รูปที่ 2

องค์ประกอบที่ผสานมาจากไฟล์ Manifest ที่มีลำดับความสำคัญต่ำกว่า ถูกไฮไลต์ด้วยสีต่างๆ ทางด้านซ้าย คีย์ของแต่ละสีคือ ที่ระบุไว้ในแหล่งที่มาของไฟล์ Manifest

รูปที่ 2 มุมมองไฟล์ Manifest แบบรวม

ไฟล์ Manifest ซึ่งเป็นส่วนหนึ่งของบิลด์แต่ไม่ได้ร่วมให้องค์ประกอบหรือ จะแสดงอยู่ในส่วนไฟล์ Manifest อื่นๆ

หากต้องการดูข้อมูลเกี่ยวกับแหล่งที่มาขององค์ประกอบ ให้คลิกด้านซ้าย และรายละเอียดจะปรากฏในส่วนบันทึกการรวม

หากมีความขัดแย้งเกิดขึ้น ความขัดแย้งนั้นจะปรากฏในข้อผิดพลาดการรวม คำแนะนำวิธีแก้ไขความขัดแย้งโดยใช้ เครื่องหมายกฎการผสาน

ข้อผิดพลาดจะพิมพ์ลงในหน้าต่างบันทึกเหตุการณ์ด้วย หากต้องการดู ให้เลือก มุมมอง > หน้าต่างเครื่องมือ > บันทึกเหตุการณ์

หากต้องการดูบันทึกทั้งหมดของโครงสร้างการตัดสินใจการรวม คุณสามารถดู ไฟล์บันทึกในไดเรกทอรี build/outputs/logs/ ของโมดูล โดยมีชื่อว่า manifest-merger-buildVariant-report.txt

ผสานนโยบาย

เครื่องมือผสานไฟล์ Manifest สามารถจับคู่องค์ประกอบ XML ทุกรายการจากไฟล์ Manifest เดียวอย่างสมเหตุสมผล ลงในเอลิเมนต์ที่เกี่ยวข้องในไฟล์อื่น การผสานจะจับคู่องค์ประกอบแต่ละรายการ ใช้คีย์การจับคู่ ซึ่งเป็นค่าแอตทริบิวต์ที่ไม่ซ้ำกัน (เช่น android:name) หรือ ความเป็นเอกลักษณ์ตามธรรมชาติของแท็ก (ตัวอย่างเช่น สามารถมีแท็ก <supports-screen>)

หากไฟล์ Manifest 2 รายการมีองค์ประกอบ XML เดียวกัน เครื่องมือจะรวมองค์ประกอบ 2 อย่างเข้าด้วยกันโดยใช้นโยบายการผสาน 1 ใน 3 นโยบายต่อไปนี้

รวม
รวมแอตทริบิวต์ทั้งหมดที่ไม่ขัดแย้งกันลงในแท็กเดียวกันและผสาน องค์ประกอบย่อยตามนโยบายการผสานรวมที่เกี่ยวข้อง หากมีแอตทริบิวต์ ให้ขัดแย้งกัน ให้รวมเข้าด้วยกันด้วยเครื่องหมายกฎการรวม
รวมรายการย่อยเท่านั้น
อย่ารวมหรือรวมแอตทริบิวต์ (เก็บเฉพาะแอตทริบิวต์ที่ระบุ ตามไฟล์ Manifest ที่มีลำดับความสำคัญสูงสุด) และผสาน องค์ประกอบย่อยตามนโยบายการผสานรวม
Keep
ปล่อยองค์ประกอบไว้ตามเดิมและเพิ่มลงในองค์ประกอบระดับบนสุดทั่วไปใน ไฟล์ที่ผสานรวมแล้ว ซึ่งจะใช้เมื่อสามารถทำให้เกิด การประกาศขององค์ประกอบเดียวกัน

ตารางที่ 3 แสดงองค์ประกอบแต่ละประเภท ประเภทของนโยบายการผสานที่ใช้ และ คีย์ที่ใช้ในการกำหนดการจับคู่องค์ประกอบระหว่างไฟล์ Manifest 2 รายการดังนี้

ตารางที่ 3 นโยบายการรวมองค์ประกอบไฟล์ Manifest คีย์การจับคู่

ธาตุ นโยบายการรวม คีย์การจับคู่
<action> รวม แอตทริบิวต์ android:name
<activity> รวม แอตทริบิวต์ android:name
<application> รวม มีเพียง 1 แพ็กเกจต่อ <manifest>
<category> รวม แอตทริบิวต์ android:name
<data> รวม มีเพียง 1 แพ็กเกจต่อ <intent-filter>
<grant-uri-permission> รวม มีเพียง 1 แพ็กเกจต่อ <provider>
<instrumentation> รวม แอตทริบิวต์ android:name
<intent-filter> Keep ไม่มีรายการที่ตรงกัน อนุญาตให้มีการประกาศได้หลายรายการภายในองค์ประกอบระดับบนสุด
<manifest> รวมรายการย่อยเท่านั้น มีเพียง 1 ไฟล์ต่อไฟล์
<meta-data> รวม แอตทริบิวต์ android:name
<path-permission> รวม มีเพียง 1 แพ็กเกจต่อ <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> รวม มีเพียง 1 แพ็กเกจต่อ <manifest>
<uses-configuration> รวม มีเพียง 1 แพ็กเกจต่อ <manifest>
<uses-feature> รวม android:name (หากไม่มี ระบบจะใช้แอตทริบิวต์ android:glEsVersion)
<uses-library> รวม แอตทริบิวต์ android:name
<uses-permission> รวม แอตทริบิวต์ android:name
<uses-sdk> รวม มีเพียง 1 แพ็กเกจต่อ <manifest>
องค์ประกอบที่กำหนดเอง รวม ไม่มีรายการที่ตรงกัน ข้อมูลเหล่านี้ของเครื่องมือผสานและ ที่รวมอยู่ในไฟล์ Manifest ที่ผสานรวมแล้ว

แทรกตัวแปรบิวด์เข้าไปในไฟล์ Manifest

หากคุณต้องการแทรกตัวแปรลงในไฟล์ AndroidManifest.xml ที่ ในไฟล์ build.gradle คุณสามารถทำได้ด้วย พร็อพเพอร์ตี้ manifestPlaceholders พร็อพเพอร์ตี้นี้ใช้การแมปคู่คีย์-ค่า ดังที่แสดงที่นี่

ดึงดูด

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

Kotlin

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

จากนั้นคุณสามารถแทรกตัวยึดตำแหน่งตัวใดตัวหนึ่งลงในไฟล์ Manifest ค่าแอตทริบิวต์:

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

โดยค่าเริ่มต้น เครื่องมือสร้างแอปยัง รหัสแอปพลิเคชัน ในตัวยึดตำแหน่ง ${applicationId} ค่าตรงกับค่าสุดท้ายเสมอ รหัสแอปพลิเคชันสำหรับบิลด์ปัจจุบัน รวมถึง การเปลี่ยนแปลงตามตัวแปรของบิลด์ วิธีนี้มีประโยชน์เมื่อคุณต้องการใช้เนมสเปซที่ไม่ซ้ำกันสำหรับตัวระบุ เช่น การดำเนินการผ่าน Intent แม้แต่ระหว่างตัวแปรของบิลด์

ตัวอย่างเช่น หากไฟล์ build.gradle มีลักษณะดังนี้

ดึงดูด

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

Kotlin

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

จากนั้นคุณจะสามารถแทรกรหัสแอปพลิเคชันในไฟล์ Manifest ดังนี้

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

และผลลัพธ์ของไฟล์ Manifest เมื่อคุณสร้าง รสชาติของผลิตภัณฑ์มีดังนี้

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

สำหรับข้อมูลเพิ่มเติม โปรดอ่าน ตั้งค่ารหัสแอปพลิเคชัน