בדף הזה נסביר איך פועל מיזוג המניפסט ואיך אפשר להשתמש בו העדפות ל: לפתור התנגשויות מיזוג. להיכרות עם האפליקציה בקובץ המניפסט, סקירה כללית של מניפסט האפליקציה.
מיזוג מספר קובצי מניפסט
ה-APK או הקובץ של קובץ Android App Bundle יכול להכיל רק פריט אחד
קובץ אחד (AndroidManifest.xml
), אבל ייתכן שפרויקט Android Studio מכיל
מספר קובצי מניפסט שסופקו על ידי קבוצת המקור הראשית, וריאנטים של build,
של הספריות. כשבונים את האפליקציה, מתבצע מיזוג של גרסת ה-build של Gradle
את כל קובצי המניפסט בקובץ מניפסט אחד שארוז
לאפליקציה.
הכלי למיזוג מניפסטים משלב את כל רכיבי ה-XML מכל קובץ באמצעות הפעולות הבאות למזג היוריסטיקה וציות להעדפות המיזוג שהגדרתם עם מאפייני XML מיוחדים.
טיפ: כדאי להשתמש במניפסט המיזוג לתצוגה מקדימה, שמתואר בקטע הבא, כדי לראות תצוגה מקדימה של תוצאות המניפסט שמוזג ולמצוא סתירה שגיאות.
מיזוג עדיפויות
כלי המיזוג משלב את כל קובצי המניפסט לקובץ אחד ברצף, בהתאם לעדיפות של כל קובץ מניפסט. לדוגמה, אם יש לך שלושה קובצי מניפסט, המניפסט בעל העדיפות הנמוכה ביותר ממוזג המניפסט בעל העדיפות הבאה, ולאחר מכן הוא ממוזג עם העדיפות הגבוהה ביותר כפי שמתואר באיור 1.
יש שלושה סוגים בסיסיים של קובצי מניפסט שניתן למזג עם כל אחד מהם אחר, ועדיפות המיזוג שלהם היא ככה (העדיפות הגבוהה ביותר ראשונה):
- קובץ מניפסט של
וריאנט build
אם יש כמה קבוצות מקור לווריאציה, סדר העדיפויות של המניפסט הוא:
- בניית מניפסט של וריאנט (למשל
src/demoDebug/
) - מניפסט של סוג build (למשל
src/debug/
) - מניפסט טעם של מוצר (למשל
src/demo/
)אם משתמשים במאפייני טעם, סדר העדיפויות של המניפסט שתואמים לסדר שבו מופיע כל מאפיין נכס
flavorDimensions
(העדיפות הראשונה היא הגבוהה ביותר).
- בניית מניפסט של וריאנט (למשל
- קובץ המניפסט הראשי של מודול האפליקציה
- קובץ מניפסט מספרייה כלולה
אם יש לך כמה ספריות, סדר העדיפויות למניפסט שלהן תואם הסדר שבו הם מופיעים ב-Gradle חסימה אחת (
dependencies
).
לדוגמה, מניפסט של ספרייה ממוזג למניפסט הראשי, ימוזג למניפסט של גרסת ה-build. לתשומת ליבכם: אלה אותן מיזוג עדיפויות לכל קבוצות המקור, כפי שמתואר פיתוח באמצעות קבוצות מקורות
חשוב:
הקובץ build.gradle
מבטל את כל המאפיינים התואמים
קובץ מניפסט שמוזג. לדוגמה,
minSdk
מ-build.gradle
או
קובץ build.gradle.kts
מבטל את מאפיין ההתאמה שצוין
<uses-sdk>
רכיב מניפסט. כדי למנוע בלבול, השמטת את
<uses-sdk>
ולהגדיר את המאפיינים האלה רק
קובץ build.gradle
. פרטים נוספים זמינים במאמר
הגדרת ה-build.
היוריסטיקה של מיזוג מיזוג
כלי המיזוג יכול להתאים באופן לוגי לכל רכיב XML ממניפסט אחד לרכיב התואם במניפסט אחר. לפרטים על אופן ההתאמה פועלות, ועיינו בעדיפות המיזוג שבקטע הקודם.
אם רכיב מהמניפסט בעדיפות נמוכה לא תואם לרכיבים המניפסט בעל העדיפות הגבוהה יותר, והוא יתווסף למניפסט הממוזג. אבל, לפעמים אם יש רכיב תואם, כלי המיזוג ינסה לשלב את כל המאפיינים מכל אחד מהם לרכיב אחד. אם הכלי מוצא ששניהם המניפסטים מכילים את אותו מאפיין עם ערכים שונים, ואז מיזוג מתרחשת התנגשות.
טבלה 1 מציגה את התוצאות האפשריות כשכלי המיזוג מנסה לשלב את כל המאפיינים לאותו רכיב.
מאפיין בעדיפות גבוהה | מאפיין בעדיפות נמוכה | תוצאת המיזוג של המאפיין |
---|---|---|
חסרת חשיבות | חסרת חשיבות | אין ערך (יש להשתמש בערך ברירת המחדל) |
ערך ב' | ערך ב' | |
ערך א' | חסרת חשיבות | ערך א' |
ערך א' | ערך א' | |
ערך ב' | שגיאה מתנגשת – עליך להוסיף סימון כלל למיזוג. |
עם זאת, יש כמה מצבים שבהם כלי המיזוג מתנהג אחרת כדי למנוע התנגשויות מיזוג:
- המאפיינים ברכיב
<manifest>
אף פעם לא ממוזגים את כל החלקים, המערכת תשתמש רק במאפיינים מהמניפסט בעל העדיפות הגבוהה ביותר. - המאפיין
android:required
בקובץ<uses-feature>
וגם רכיבי<uses-library>
מיזוג OR. אם יש התנגשות,"true"
נחשב מוחלת, והתכונה או הספרייה שנדרשת על ידי מניפסט אחד תמיד נכללות. - מאפיינים במסגרת
רכיב
<uses-sdk>
תמיד ישתמש בערך שבמאפיין מניפסט בעדיפות גבוהה יותר, חוץ מאשר במצבים הבאים:- כשיש למניפסט בעדיפות נמוכה יותר ערך
minSdk
גבוה יותר, תתרחש שגיאה אלא אם להחיל את כלל מיזוגoverrideLibrary
. - כשיש למניפסט בעדיפות נמוכה יותר
targetSdkVersion
נמוך יותר, כלי המיזוג משתמש בערך מהמניפסט בעדיפות גבוהה יותר, והוא גם מוסיף הרשאות מערכת שנחוצים כדי להבטיח שהספרייה המיובאת תמשיך פועלות כראוי (במקרים שבהם בגרסה העדכנית יותר של Android הגדלת הגבלות על הרשאות). מידע נוסף בנושא על התנהגות המשתמשים, קראו את הקטע על מערכת משתמעת הרשאות.
- כשיש למניפסט בעדיפות נמוכה יותר ערך
- הרכיב
<intent-filter>
אף פעם לא תואם מניפסטים. כל אחד מהם נחשב לייחודי נוסף לרכיב ההורה המשותף במניפסט המוזג.
בכל מקרה אחר של התנגשות בין מאפיינים, תקבלו שגיאה ותצטרכו להנחות את כלי המיזוג איך לפתור את הבעיה על ידי הוספת מאפיין מיוחד לקובץ המניפסט בעדיפות גבוהה יותר. אפשר לעיין בקטע הבא לגבי סמלים של כללי מיזוג.
אין להסתמך על ערכי המאפיינים המוגדרים כברירת מחדל. כי כל
שהמאפיינים הייחודיים שלהם משולבים באותו רכיב,
תוצאות בלתי צפויות אם המניפסט בעל העדיפות הגבוהה יותר בפועל תלוי
ערך ברירת המחדל של מאפיין בלי להצהיר עליו. לדוגמה, אם הערך הגבוה יותר של
במניפסט העדיפות אין הצהרה על android:launchMode
, נשתמש בערך ברירת המחדל של "standard"
- אבל אם
במניפסט בעדיפות נמוכה יותר מוצהר על המאפיין הזה עם ערך אחר,
הערך יוחל על המניפסט הממוזג, שיבטל את ערך ברירת המחדל. שלך
צריך להגדיר כל מאפיין באופן מפורש כמו שרוצים. ערכי ברירת מחדל
של כל מאפיין מתועדים בקובץ
הפניה למניפסט.
סמני מיזוג של כללים
סמן של כלל מיזוג הוא מאפיין XML שבו אפשר להשתמש כדי לבטא את ההעדפה שלכם על פתרון התנגשויות מיזוג או הסרה של רכיבים ומאפיינים לא רצויים. ניתן להחיל סמן על רכיב שלם או על רכיב ספציפי בלבד ברכיב מסוים.
כשממזגים שני קובצי מניפסט, כלי המיזוג מחפש את הסמנים האלה קובץ מניפסט בעדיפות גבוהה יותר.
כל הסמנים שייכים למרחב השמות של Android tools
, לכן צריך להצהיר עליו קודם
מרחב השמות הזה ברכיב <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"
- ליצור כשל ב-build בכל פעם שהרכיב הזה בעדיפות נמוכה יותר
המניפסט לא תואם בדיוק לרכיב שבמניפסט בעדיפות גבוהה יותר (אלא אם
נפתרה באמצעות סמנים אחרים של כללי מיזוג). ההגדרה הזו מבטלת את היוריסטיקה של המיזוג של ההתנגשויות. עבור
לדוגמה, אם המניפסט בעדיפות נמוכה יותר כולל מאפיין נוסף,
ה-build נכשל (ובעוד שהתנהגות ברירת המחדל מוסיפה את המאפיין הנוסף
את המניפסט הממוזג).
מניפסט בעדיפות נמוכה:
<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, ..."
- ליצור כשל build בכל פעם שהמאפיינים האלה
המניפסט בעדיפות נמוכה יותר לא תואם בדיוק למאפיינים בעדיפות הגבוהה יותר
. זו התנהגות ברירת המחדל לכל המאפיינים, מלבד
כאלה עם התנהגות מיוחדת, כפי שמתואר במאמר היוריסטיקה של מיזוג התנגשויות.
מניפסט בעדיפות נמוכה:
<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 מפורטות כל ההרשאות האפשריות שניתן להוסיף למניפסט הממוזג שלך:
הצהרה במניפסט בעדיפות נמוכה יותר | ההרשאות נוספו למניפסט הממוזג |
---|---|
הערך של targetSdkVersion הוא 3 ומטה |
WRITE_EXTERNAL_STORAGE , READ_PHONE_STATE |
targetSdkVersion בן 15 ומטה ומשתמש ב-READ_CONTACTS |
READ_CALL_LOG |
targetSdkVersion בן 15 ומטה ומשתמש ב-WRITE_CONTACTS |
WRITE_CALL_LOG |
בדיקת המניפסט שמוזג ואיתור התנגשויות
עוד לפני בניית האפליקציה, אפשר לראות תצוגה מקדימה של התוכן שמוזג נראה כמו מניפסט. כדי להציג תצוגה מקדימה, מבצעים את הפעולות הבאות:
- ב-Android Studio, פותחים את הקובץ
AndroidManifest.xml
. - לוחצים על הכרטיסייה מניפסט ממוזג בתחתית העורך.
בתצוגת המניפסט הממוזג מוצגות תוצאות המניפסט הממוזגת בצד ימין ומידע על כל קובץ מניפסט ממוזג בצד ימין, כפי שמוצג איור 2.
הרכיבים שמוזגו מקובצי מניפסט בעדיפות נמוכה מודגשים בצבעים שונים בצד שמאל. המפתח לכל צבע הוא שצוינו בקטע מקורות מניפסט.
קובצי מניפסט שהיו חלק מה-build אבל לא תרמו רכיבים או המאפיינים מפורטים בקטע קובצי מניפסט אחרים.
כדי לראות מידע על מקור הרכיב, לוחצים עליו בצד ימין והפרטים יופיעו בקטע יומן מיזוג.
אם יש סתירות, הן מופיעות בקטע שגיאות מיזוג. עם המלצה לפתרון המחלוקת באמצעות סמלים של כללי מיזוג.
השגיאות מודפסות גם בחלון יומן אירועים. כדי להציג אותן, בוחרים תצוגה > Windows בכלי > יומן אירועים.
כדי לראות יומן מלא של עץ ההחלטות בתהליך המיזוג, אפשר
קובץ היומן בספריית build/outputs/logs/
של המודול, שנקרא
manifest-merger-buildVariant-report.txt
.
מדיניות מיזוג
הכלי למיזוג מניפסטים יכול להתאים באופן לוגי לכל רכיב XML ממניפסט אחד
לרכיב תואם בקובץ אחר. המיזוג תואם לכל רכיב
באמצעות מפתח התאמה, ערך מאפיין ייחודי (כמו android:name
) או
הייחודיות הטבעית של התג עצמו (לדוגמה, יכול להיות רק תג אחד
רכיב <supports-screen>
).
אם שני מניפסטים כוללים את אותו רכיב XML, אז הכלי ממזג את שני הרכיבים באמצעות אחת מתוך שלוש כללי מדיניות מיזוג:
- מיזוג
- לשלב את כל המאפיינים שאינם מתנגשים לאותו תג ולמזג של רכיבי צאצא בהתאם למדיניות המיזוג המתאימה להם. אם יש מאפיינים כלשהם מתנגשים זה עם זה, למזג אותם יחד באמצעות סמני כללי המיזוג.
- מיזוג של ילדים בלבד
- אין לשלב או למזג את המאפיינים (יש לשמור רק את המאפיינים שצוינו לפי קובץ המניפסט בעל העדיפות הגבוהה ביותר) וממזגים של רכיבי צאצא בהתאם למדיניות המיזוג שלהם.
- Keep
- משאירים את הרכיב כפי שהוא ומוסיפים אותו לרכיב ההורה המשותף שמוזג. אפשר להשתמש באפשרות הזו רק במקרים שבהם יכול להיות שיהיו כמה או הצהרות על אותו רכיב.
טבלה 3 מפרטת כל סוג רכיב, סוג מדיניות המיזוג שבה נעשה שימוש מפתח המשמש לקביעת התאמה של רכיב בין שני מניפסטים:
רכיב | מדיניות מיזוג | מפתח התאמה |
---|---|---|
<action>
|
מיזוג | מאפיין android:name
|
<activity>
|
מיזוג | מאפיין android:name
|
<application>
|
מיזוג | יש רק אפשרות אחת לכל <manifest> .
|
<category>
|
מיזוג | מאפיין android:name
|
<data>
|
מיזוג | יש רק אפשרות אחת לכל <intent-filter> .
|
<grant-uri-permission>
|
מיזוג | יש רק אפשרות אחת לכל <provider> .
|
<instrumentation>
|
מיזוג | מאפיין android:name
|
<intent-filter>
|
Keep | אין התאמה. מותרות מספר הצהרות בתוך רכיב ההורה. |
<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> .
|
רכיבים מותאמים אישית | מיזוג | אין התאמה. הם לא מוכרים לכלי המיזוג, והם תמיד כלולה במניפסט המוזג. |
החדרת משתני build למניפסט
אם אתם צריכים להוסיף משתנים לקובץ AndroidManifest.xml
שהגדרתם בקובץ build.gradle
, אפשר לעשות את זה באמצעות
נכס manifestPlaceholders
. המאפיין הזה לוקח מפה של צמדי מפתח-ערך,
כפי שמוצג כאן:
מגניב
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] } ... }
Kotlin
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" } ... }
לאחר מכן אפשר להוסיף אחד מה-placeholders לקובץ המניפסט בתור ערך המאפיין:
<intent-filter ... >
<data android:scheme="https" android:host="${hostName}" ... />
...
</intent-filter>
כברירת מחדל, כלי ה-build מספקים גם את
מזהה האפליקציה
ב-placeholder של ${applicationId}
. הערך תמיד תואם לערך הסופי
ב-build הנוכחי של האפליקציה, כולל
משתנים בהתאם לווריאציות של ה-build.
האפשרות הזו שימושית כשרוצים להשתמש במרחב שמות ייחודי למזהים
כמו פעולת Intent, גם בין הווריאציות של ה-build.
לדוגמה, אם הקובץ 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" } } }
לאחר מכן אפשר להזין את מזהה האפליקציה במניפסט כך:
<intent-filter ... >
<action android:name="${applicationId}.TRANSMOGRIFY" />
...
</intent-filter>
ותוצאת המניפסט כאשר טעם המוצר הוא:
<intent-filter ... >
<action android:name="com.example.myapp.free.TRANSMOGRIFY" />
...
</intent-filter>
מידע נוסף זמין במאמר הבא: מגדירים את מזהה האפליקציה.