Na tej stronie opisujemy, jak działa scalanie pliku manifestu i jak możesz zastosować preferencje scalania, aby rozwiązać konflikty scalania. Więcej informacji o pliku manifestu aplikacji znajdziesz w artykule Omówienie pliku manifestu aplikacji.
Scalanie wielu plików manifestu
Plik APK lub pakiet Android App Bundle może zawierać tylko jeden plik AndroidManifest.xml
, ale projekt w Android Studio może zawierać kilka plików MANIFEST dostarczonych przez główny zestaw źródeł, warianty kompilacji i zaimportowane biblioteki. Podczas kompilowania aplikacji kompilacja Gradle łączy wszystkie pliki manifestu w jeden plik manifestu, który jest pakowany do aplikacji.
Narzędzie do łączenia plików manifestu łączy wszystkie elementy XML z każdego pliku, stosując heurystyki łączenia i przestrzegając preferencji zdefiniowanych za pomocą specjalnych atrybutów XML.
Wskazówka: aby wyświetlić podgląd wyników z połączonego pliku manifestu i znaleźć błędy związane z konfliktami, użyj widoku Połączony plik manifestu opisanego w następującej sekcji.
scalanie priorytetów,
Narzędzie do łączenia łączy wszystkie pliki manifestu w jeden plik, sekwencyjnie, na podstawie priorytetu każdego pliku manifestu. Jeśli na przykład masz 3 pliki manifestu, manifest o najniższym priorytecie jest scalany z manifesem o drugim najwyższym priorytecie, a ten z manifesem o najwyższym priorytecie, jak pokazano na rysunku 1.

Istnieją 3 podstawowe typy plików manifestu, które można łączyć ze sobą. Priorytety łączenia są następujące (najpierw najwyższy priorytet):
- Plik manifestu dla wariantu kompilacji
Jeśli masz wiele zbiorów źródeł dla danego wariantu, ich priorytety w pliku manifestu są następujące:
- Plik manifestu wariantu kompilacji (np.
src/demoDebug/
) - Plik manifestu typu kompilacji (np.
src/debug/
) - Plik manifestu wariantu usługi (np.
src/demo/
)Jeśli używasz wymiarów smaków, priorytety w pliku manifestu odpowiadają kolejności, w jakiej poszczególne wymiary są wymienione w właściwości
flavorDimensions
(pierwszy ma najwyższy priorytet).
- Plik manifestu wariantu kompilacji (np.
- Główny plik manifestu modułu aplikacji
- Plik manifestu z uwzględnionej biblioteki
Jeśli masz wiele bibliotek, ich priorytety w pliku manifestu odpowiadają kolejności, w jakiej występują w bloku Gradle
dependencies
.
Na przykład manifest biblioteki jest scalany z głównym plikiem manifestu, a główny plik manifestu jest scalany z pliku manifestu wariantu kompilacji. Pamiętaj, że są to te same priorytety scalania dla wszystkich zbiorów źródeł, jak opisano w artykule Tworzenie zasobów z użyciem zbiorów źródeł.
Ważne: konfiguracje kompilacji z pliku build.gradle
zastępują wszystkie odpowiadające im atrybuty w pliku scalonego pliku manifestu. Na przykład atrybut
minSdk
z pliku build.gradle
lub
build.gradle.kts
zastępuje odpowiadający atrybut w elemencie manifestu <uses-sdk>
. Aby uniknąć nieporozumień, pomiń element <uses-sdk>
i zdefiniuj te właściwości tylko w pliku build.gradle
. Więcej informacji znajdziesz w artykule Konfigurowanie kompilacji.
Heurystyka konfliktów scalania
Narzędzie do łączenia może logicznie dopasować każdy element XML z jednego pliku manifestu do odpowiadającego mu elementu w drugim pliku manifestu. Szczegółowe informacje o tym, jak działa dopasowywanie, znajdziesz w sekcji Priorytety scalania.
Jeśli element z pliku manifestu o niższym priorytecie nie pasuje do żadnego elementu w pliku manifestu o wyższym priorytecie, jest dodawany do scalonego pliku manifestu. Jeśli jednak znajdzie się element pasujący do innych, narzędzie do łączenia próbuje połączyć wszystkie atrybuty z każdego z nich w jednym elemencie. Jeśli narzędzie wykryje, że oba manifesty zawierają ten sam atrybut z różnymi wartościami, wystąpi konflikt scalania.
Tabela 1 przedstawia możliwe wyniki, gdy narzędzie do łączenia próbuje połączyć wszystkie atrybuty w tym samym elemencie.
Tabela 1. Domyślne zachowanie podczas łączenia wartości atrybutów
Atrybut o wysokim priorytecie | Atrybut o niskim priorytecie | Wynik po scaleniu atrybutu |
---|---|---|
Nieistotna | Nieistotna | Brak wartości (użyj wartości domyślnej) |
Wartość B | Wartość B | |
Wartość A | Nieistotna | Wartość A |
Wartość A | Wartość A | |
Wartość B | Błąd konfliktu – musisz dodać znacznik reguły scalania. |
Są jednak sytuacje, w których narzędzie do łączenia zachowuje się inaczej, aby uniknąć konfliktów podczas łączenia:
- Atrybuty w elemencie
<manifest>
nigdy nie są łączone; używane są tylko atrybuty z manifesztu o najwyższym priorytecie. - Atrybut
android:required
w elementach<uses-feature>
i<uses-library>
korzysta z operacji OR. Jeśli wystąpi konflikt, zostanie zastosowana funkcja"true"
, a funkcja lub biblioteka wymagana przez jeden manifest jest zawsze uwzględniana. - Atrybuty w elemencie
<uses-sdk>
zawsze używają wartości z pliku manifestu o wyższym priorytecie, z wyjątkiem tych sytuacji:- Jeśli manifest o niższym priorytecie ma wyższą wartość
minSdk
, wystąpi błąd, chyba że zastosujesz regułę łączeniaoverrideLibrary
. - Jeśli plik manifestu o niższym priorytecie ma niższą wartość parametru
targetSdkVersion
, narzędzie do łączenia używa wartości z pliku manifestu o wyższym priorytecie. Dodaje też uprawnienia systemowe, które są niezbędne, aby zaimportowana biblioteka nadal działała prawidłowo (w przypadku, gdy nowsza wersja Androida ma zwiększone ograniczenia dotyczące uprawnień). Więcej informacji o tym zachowaniu znajdziesz w sekcji dotyczącej domyślnych uprawnień systemowych.
- Jeśli manifest o niższym priorytecie ma wyższą wartość
- Element
<intent-filter>
nigdy nie jest dopasowywany między plikami manifestu. Każdy z nich jest traktowany jako unikalny i dodawany do wspólnego elementu nadrzędnego w scalonym pliku manifestu.
W przypadku wszystkich innych konfliktów między atrybutami pojawi się błąd. Musisz wtedy przekazać narzędziu do łączenia instrukcje dotyczące jego rozwiązania, dodając specjalny atrybut w pliku manifestu o wyższym priorytecie. Zapoznaj się z następną sekcją dotyczącą znaczników reguł scalania.
Nie polegaj na wartościach domyślnych atrybutów. Wszystkie unikalne atrybuty są łączone w tym samym elemencie, co może powodować nieoczekiwane wyniki, jeśli manifest o wyższym priorytecie zależy od domyślnej wartości atrybutu bez jego zadeklarowania. Jeśli na przykład plik manifestu o wyższym priorytecie nie deklaruje atrybutu android:launchMode
, używa wartości domyślnej "standard"
. Jeśli jednak plik manifestu o niższym priorytecie deklaruje ten atrybut z inną wartością, ta wartość jest stosowana w złączonym pliku manifestu, co zastępuje wartość domyślną. Należy wyraźnie zdefiniować każdy atrybut. Wartości domyślne każdego atrybutu są opisane w dokumentacji pliku manifestu.
znaczniki reguł scalania,
Znak znacznika reguły scalania to atrybut XML, za pomocą którego możesz określić preferowany sposób rozwiązywania konfliktów podczas scalania lub usuwania niechcianych elementów i atrybutów. Możesz zastosować znacznik do całego elementu lub tylko do określonych atrybutów w elemencie.
Podczas łączenia 2 plików pliku manifestu narzędzie do łączenia szuka tych znaczników w pliku manifestu o wyższym priorytecie.
Wszystkie znaczniki należą do przestrzeni nazw Android tools
, więc musisz najpierw zadeklarować tę przestrzeń nazw w elemencie <manifest>
, jak pokazano poniżej:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" xmlns:tools="http://schemas.android.com/tools">
znaczniki węzłów,
Aby zastosować regułę łączenia do całego elementu XML (do wszystkich atrybutów w danym elemencie pliku manifestu i do wszystkich jego tagów podrzędnych), użyj tych atrybutów:
tools:node="merge"
- Połącz wszystkie atrybuty w tym tagu i wszystkie elementy zagnieżdżone, jeśli nie ma konfliktów, używając heurystyki łączenia konfliktów. Jest to domyślne zachowanie elementów.
Manifest o niskim priorytecie:
<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 o wysokim priorytecie:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:node="merge"> </activity>
Wynik po scaleniu pliku manifestu:
<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"
- Połącz atrybuty tylko w tym tagu; nie łącz elementów zagnieżdżonych.
Manifest o niskim priorytecie:
<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 o wysokim priorytecie:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:node="merge-only-attributes"> </activity>
Wynik po scaleniu pliku manifestu:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" android:windowSoftInputMode="stateUnchanged"> </activity>
tools:node="remove"
- Usuń ten element z pliku manifestu. Używany, gdy w złączonym pliku manifestu znajdziesz element, którego nie potrzebujesz i który został dostarczony przez plik manifestu o niższym priorytecie, na który nie masz wpływu (np. zaimportowana biblioteka).
Manifest o niskim priorytecie:
<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 o wysokim priorytecie:
<activity-alias android:name="com.example.alias"> <meta-data android:name="cow" tools:node="remove"/> </activity-alias>
Wynik po scaleniu pliku manifestu:
<activity-alias android:name="com.example.alias"> <meta-data android:name="duck" android:value="@string/quack"/> </activity-alias>
tools:node="removeAll"
- Podobna do
tools:node="remove"
, ale usuwa wszystkie elementy pasujące do tego typu elementu (w tym samym elemencie nadrzędnym).Manifest o niskim priorytecie:
<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 o wysokim priorytecie:
<activity-alias android:name="com.example.alias"> <meta-data tools:node="removeAll"/> </activity-alias>
Wynik po scaleniu pliku manifestu:
<activity-alias android:name="com.example.alias"> </activity-alias>
tools:node="replace"
- Całkowicie zastąp element o niższym priorytecie. Oznacza to, że jeśli w pliku manifestu o niższym priorytecie znajduje się element pasujący do elementu w pliku manifestu o wyższym priorytecie, zignoruj ten pierwszy i użyj tego drugiego dokładnie tak, jak jest on zapisany w pliku manifestu.
Manifest o niskim priorytecie:
<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 o wysokim priorytecie:
<activity-alias android:name="com.example.alias" tools:node="replace"> <meta-data android:name="fox" android:value="@string/dingeringeding"/> </activity-alias>
Wynik po scaleniu pliku manifestu:
<activity-alias android:name="com.example.alias"> <meta-data android:name="fox" android:value="@string/dingeringeding"/> </activity-alias>
tools:node="strict"
- Wygeneruj błąd kompilacji, gdy element w pliku manifestu o niższym priorytecie nie jest identyczny z elementem w pliku manifestu o wyższym priorytecie (chyba że został rozwiązany przez inne znaczniki reguły scalania). Zastąpi to heurystyki konfliktów scalania. Jeśli na przykład manifest o niższym priorytecie zawiera dodatkowy atrybut, kompilacja zakończy się niepowodzeniem (gdyż zachowanie domyślne spowoduje dodanie tego atrybutu do scalonego pliku manifestu).
Manifest o niskim priorytecie:
<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 o wysokim priorytecie:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:node="strict"> </activity>
Spowoduje to błąd scalania pliku manifestu. W trybie ścisłym te 2 elementy pliku manifestu nie mogą się w ogóle różnić. Aby rozwiązać te różnice, musisz zastosować inne znaczniki reguły scalania. (bez
tools:node="strict"
te 2 pliki można scalić bez błędów, jak w przypadku plikutools:node="merge"
).
znaczniki atrybutów,
Aby zamiast tego zastosować regułę scalania tylko do określonych atrybutów w tagu manifestu, użyj tych atrybutów. Każdy atrybut może zawierać co najmniej 1 nazwę atrybutu (w tym jego przestrzeń nazw) oddzieloną przecinkami.
tools:remove="attr, ..."
- Usuń określone atrybuty z pliku manifestu po scalerowaniu.
Używany, gdy plik manifestu o niższym priorytecie zawiera te atrybuty i chcesz mieć pewność, że nie zostaną one uwzględnione w złączonym pliku manifestu.
Manifest o niskim priorytecie:
<activity android:name="com.example.ActivityOne" android:windowSoftInputMode="stateUnchanged">
Manifest o wysokim priorytecie:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:remove="android:windowSoftInputMode">
Wynik po scaleniu pliku manifestu:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait">
tools:replace="attr, ..."
- Zastąp określone atrybuty w pliku manifestu o niższym priorytecie atrybutami z tego pliku. Innymi słowy, zawsze zachowuj wartości z pliku manifestu o wyższym priorytecie.
Manifest o niskim priorytecie:
<activity android:name="com.example.ActivityOne" android:theme="@oldtheme" android:exported="false" android:windowSoftInputMode="stateUnchanged">
Manifest o wysokim priorytecie:
<activity android:name="com.example.ActivityOne" android:theme="@newtheme" android:exported="true" android:screenOrientation="portrait" tools:replace="android:theme,android:exported">
Wynik po scaleniu pliku manifestu:
<activity android:name="com.example.ActivityOne" android:theme="@newtheme" android:exported="true" android:screenOrientation="portrait" android:windowSoftInputMode="stateUnchanged">
tools:strict="attr, ..."
- W każdym przypadku, gdy te atrybuty w pliku manifestu o niższym priorytecie nie pasują dokładnie do atrybutów w pliku manifestu o wyższym priorytecie, generuj błąd kompilacji. Jest to domyślne zachowanie we wszystkich atrybutach z wyjątkiem tych, które mają specjalne zachowania opisane w heurystychach dotyczących konfliktów podczas łączenia.
Manifest o niskim priorytecie:
<activity android:name="com.example.ActivityOne" android:screenOrientation="landscape"> </activity>
Manifest o wysokim priorytecie:
<activity android:name="com.example.ActivityOne" android:screenOrientation="portrait" tools:strict="android:screenOrientation"> </activity>
Spowoduje to błąd scalania pliku manifestu. Aby rozwiązać konflikt, musisz zastosować inne znaczniki reguły łączenia. Jest to działanie domyślne, więc ten sam wynik można uzyskać, dodając
tools:strict="screenOrientation"
.
Możesz też zastosować wiele znaczników do jednego elementu, jak w tym przykładzie:
Manifest o niskim priorytecie:
<activity android:name="com.example.ActivityOne" android:theme="@oldtheme" android:exported="false" android:allowTaskReparenting="true" android:windowSoftInputMode="stateUnchanged">
Manifest o wysokim priorytecie:
<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">
Wynik po scaleniu pliku manifestu:
<activity android:name="com.example.ActivityOne" android:theme="@newtheme" android:exported="true" android:allowTaskReparenting="true" android:screenOrientation="portrait">
Selektor znaczników
Jeśli chcesz zastosować znaczniki reguły scalania tylko do określonej zaimportowanej biblioteki, dodaj atrybut tools:selector
z nazwą pakietu biblioteki.
Na przykład w przypadku tego pliku manifestu reguła łączenia remove
jest stosowana tylko wtedy, gdy plik manifestu o niższym priorytecie pochodzi z biblioteki com.example.lib1
:
<permission android:name="permissionOne" tools:node="remove" tools:selector="com.example.lib1">
Jeśli manifest o niższym priorytecie pochodzi z dowolnego innego źródła, reguła scalania remove
zostanie zignorowana.
Uwaga: jeśli użyjesz tego w przypadku jednego z atrybutów, będzie ono dotyczyć wszystkich atrybutów określonych w tym atrybucie.
Zastępowanie atrybutu <uses-sdk> w przypadku zaimportowanych bibliotek
Domyślnie podczas importowania biblioteki z wartością minSdk
większą niż w głównym pliku manifestu występuje błąd i biblioteki nie można zaimportować.
Aby narzędzie do łączenia zignorowało ten konflikt i zaimportowało bibliotekę, zachowując przy tym niższą wartość atrybutu minSdk
w aplikacji, dodaj atrybut overrideLibrary
do tagu <uses-sdk>
.
Wartością atrybutu może być co najmniej 1 nazwa pakietu biblioteki (rozdzielona przecinkami), wskazująca biblioteki, które mogą zastąpić minSdk
w głównym pliku manifestu.
Jeśli na przykład główny plik manifestu aplikacji stosuje się do overrideLibrary
w ten sposób:
<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"/> ...
Następnie można scalić ten plik manifestu bez błędów dotyczących tagu <uses-sdk>
. Scalony plik manifestu zachowa tag minSdk="2"
z pliku manifestu aplikacji.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.lib1"> <uses-sdk android:minSdk="4" /> ...
Domyślne uprawnienia systemowe
Niektóre interfejsy API Androida, które kiedyś były swobodnie dostępne dla aplikacji, zostały w ostatnich wersjach Androida objęte uprawnieniami systemowymi.
Aby uniknąć problemów z aplikacjami, które wymagają dostępu do tych interfejsów API, najnowsze wersje Androida umożliwiają aplikacjom dalszy dostęp do tych interfejsów API bez uprawnień, jeśli wartość targetSdkVersion
jest niższa niż wersja, w której dodano ograniczenie. Takie zachowanie przyznaje aplikacji domyślne uprawnienie do uzyskiwania dostępu do interfejsów API. Może to mieć wpływ na złączone manifesty, które mają różne wartości dla targetSdkVersion
.
Jeśli plik manifestu o niższym priorytecie ma niższą wartość parametru targetSdkVersion
, która zapewnia mu domyślne uprawnienia, a plik manifestu o wyższym priorytecie nie ma tych samych domyślnych uprawnień (ponieważ wartość parametru targetSdkVersion
jest równa lub wyższa niż w wersji, w której dodano ograniczenie), narzędzie do łączenia wyraźnie dodaje uprawnienia systemowe do scalonego pliku manifestu.
Jeśli na przykład Twoja aplikacja ma wartość targetSdkVersion
równą 4 lub większą, a importowana biblioteka ma wartość targetSdkVersion
równą 3 lub mniejszą, narzędzie do łączenia dodaje uprawnienie WRITE_EXTERNAL_STORAGE
do scalonego pliku manifestu.
Tabela 2 zawiera wszystkie możliwe uprawnienia, które można dodać do scalonego pliku manifestu:
Tabela 2. Lista uprawnień, które narzędzie do łączenia może dodać do scalonego pliku manifestu
Deklaracje w pliku manifestu o niższym priorytecie | uprawnienia dodane do scalonego pliku manifestu; |
---|---|
targetSdkVersion to 3 lub mniej |
WRITE_EXTERNAL_STORAGE , READ_PHONE_STATE |
targetSdkVersion ma wartość 15 lub mniejszą i korzysta z READ_CONTACTS |
READ_CALL_LOG |
targetSdkVersion ma wartość 15 lub mniejszą i korzysta z WRITE_CONTACTS |
WRITE_CALL_LOG |
Sprawdzanie scalonego pliku manifestu i znajdowanie konfliktów
Jeszcze przed utworzeniem aplikacji możesz wyświetlić podgląd scalonego pliku manifestu. Aby wyświetlić podgląd:
- W Android Studio otwórz plik
AndroidManifest.xml
. - U dołu edytora kliknij kartę Skompilowany plik manifestu.
Widok scalonego pliku manifestu zawiera po lewej stronie wyniki scalonego pliku manifestu, a po prawej informacje o każdym scalonym pliku manifestu (patrz rys. 2).
Elementy scalone z plików pliku manifestu o niższym priorytecie są wyróżnione na żółto po lewej stronie. Klucz każdego koloru jest określony w sekcji Źródła pliku manifestu.
Rysunek 2. Widok „Manifest łączony”.
Pliki manifestu, które były częścią kompilacji, ale nie zawierały elementów ani atrybutów, są wymienione w sekcji Inne pliki manifestu.
Aby zobaczyć informacje o pochodzeniu elementu, kliknij go w panelu po lewej stronie. Szczegóły pojawią się w sekcji Log łączenia.
Jeśli wystąpią jakieś konflikty, pojawią się one w sekcji Błędy podczas łączenia wraz z rekomendacją dotyczącą sposobu ich rozwiązania za pomocą znaczników reguły łączenia.
Błędy są też wyświetlane w oknie Dziennik zdarzeń. Aby je wyświetlić, wybierz Widok > Okna narzędzia > Dziennik zdarzeń.
Aby zobaczyć pełny dziennik drzewa decyzji dotyczącego łączenia, otwórz plik dziennika o nazwie manifest-merger-buildVariant-report.txt
w katalogu build/outputs/logs/
w module.
Scalanie zasad
Narzędzie do łączenia plików manifestu może logicznie dopasować każdy element XML z jednego pliku manifestu do odpowiadającego elementu w innym pliku. Zbiorca dopasowuje każdy element za pomocą klucza dopasowania, który może być unikalną wartością atrybutu (np. android:name
) lub naturalną unikalnością samego tagu (np. może istnieć tylko jeden element <supports-screen>
).
Jeśli 2 pliki manifestu mają ten sam element XML, narzędzie scala te elementy, stosując jedną z 3 zasad scalania:
- Scal
- Połącz wszystkie atrybuty, które nie powodują konfliktów, w tym samym tagu, a także scal elementy podrzędne zgodnie z odpowiednimi zasadami scalania. Jeśli jakieś atrybuty są ze sobą sprzeczne, scal je za pomocą znaczników reguły scalania.
- Scal tylko elementy podrzędne
- Nie łącz ani nie scalaj atrybutów (zachowaj tylko atrybuty podane przez plik manifestu o najwyższym priorytecie) i scalaj elementy podrzędne zgodnie z zasadami scalania.
- Keep
- Zostaw element bez zmian i dodaj go do wspólnego elementu nadrzędnego w scalonym pliku. Jest to używane tylko wtedy, gdy dopuszczalne jest występowanie kilku deklaracji tego samego elementu.
Tabela 3 zawiera listę typów elementów, typ zasad scalania i klucz używany do określania dopasowania elementów w 2 plikach manifestu:
Tabela 3. Zasady scalania elementów pliku manifestu i klucze dopasowania
Żywioły | Scalanie zasad | Klucz dopasowania |
---|---|---|
<action>
|
Scal | Atrybut android:name
|
<activity>
|
Scal | Atrybut android:name
|
<application>
|
Scal | Każda <manifest> może mieć tylko 1 kartę.
|
<category>
|
Scal | Atrybut android:name
|
<data>
|
Scal | Każda <intent-filter> może mieć tylko 1 kartę.
|
<grant-uri-permission>
|
Scal | Każda <provider> może mieć tylko 1 kartę.
|
<instrumentation>
|
Scal | Atrybut android:name
|
<intent-filter>
|
Keep | Brak dopasowania; w elemencie nadrzędnym można umieścić kilka deklaracji. |
<manifest>
|
Scal tylko elementy podrzędne | Każdy plik może zawierać tylko jedną. |
<meta-data>
|
Scal | Atrybut android:name
|
<path-permission>
|
Scal | Każda <provider> może mieć tylko 1 kartę.
|
<permission-group>
|
Scal | Atrybut android:name
|
<permission>
|
Scal | Atrybut android:name
|
<permission-tree>
|
Scal | Atrybut android:name
|
<provider>
|
Scal | Atrybut android:name
|
<receiver>
|
Scal | Atrybut android:name
|
<screen>
|
Scal | Atrybut android:screenSize
|
<service>
|
Scal | Atrybut android:name
|
<supports-gl-texture>
|
Scal | Atrybut android:name
|
<supports-screen>
|
Scal | Każda <manifest> może mieć tylko 1 kartę.
|
<uses-configuration>
|
Scal | Każda <manifest> może mieć tylko 1 kartę.
|
<uses-feature>
|
Scal | atrybut android:name (jeśli go nie ma, to atrybut android:glEsVersion );
|
<uses-library>
|
Scal | Atrybut android:name
|
<uses-permission>
|
Scal | Atrybut android:name
|
<uses-sdk>
|
Scal | Każda <manifest> może mieć tylko 1 kartę.
|
Elementy niestandardowe | Scal | Brak dopasowania; są one nieznane dla narzędzia do scalania i zawsze są uwzględniane w scalonym pliku manifestu. |
Wstrzykiwanie zmiennych kompilacji do pliku manifestu
Jeśli chcesz wstawić do pliku AndroidManifest.xml
zmienne zdefiniowane w pliku build.gradle
, możesz to zrobić za pomocą właściwości manifestPlaceholders
. Ta właściwość przyjmuje mapę par klucz-wartość, jak pokazano poniżej:
Groovy
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] } ... }
Kotlin
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" } ... }
Następnie możesz wstawić jeden z symboli zastępczych do pliku manifestu jako wartość atrybutu:
<intent-filter ... >
<data android:scheme="https" android:host="${hostName}" ... />
...
</intent-filter>
Domyślnie narzędzia do kompilacji podają też identyfikator aplikacji w miejscu zarezerwowanym dla ${applicationId}
. Wartość zawsze odpowiada ostatecznemu identyfikatorowi aplikacji dla bieżącej wersji, w tym zmianom w wersjach wariantów.
Jest to przydatne, gdy chcesz używać unikalnej przestrzeni nazw dla identyfikatorów, takich jak działanie związane z zamiarem, nawet w przypadku wariantów kompilacji.
Jeśli na przykład plik build.gradle
wygląda tak:
Groovy
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" } } }
Następnie możesz wstawić identyfikator aplikacji w pliku manifestu w ten sposób:
<intent-filter ... >
<action android:name="${applicationId}.TRANSMOGRIFY" />
...
</intent-filter>
Gdy skompilujesz wersję „free” manifestu, otrzymasz ten wynik:
<intent-filter ... >
<action android:name="com.example.myapp.free.TRANSMOGRIFY" />
...
</intent-filter>
Więcej informacji znajdziesz w artykule Ustawianie identyfikatora aplikacji.