Android Studioでアプリをビルドしたときに、
Manifest merger failed
と表示されてビルドできないことがあります。
このエラーは、
アプリ本体のAndroidManifest.xmlと、
ライブラリやビルドバリアントなどが持つManifestの内容を統合するときに、
同じ項目へ異なる設定が指定されるなどして競合が発生した場合に表示されます。
この記事では、
Manifest merger failedが発生する主な原因と、
Android Studioで競合しているManifestを確認し、
エラーを解消する方法を順番に解説します。
- Manifest merger failedとは
- 代表的なエラー表示
- まずMerged Manifestを確認する
- 原因1:同じ属性に異なる値が設定されている
- 解決方法1:tools:replaceでアプリ側の値を使用する
- 複数の属性をtools:replaceで指定する場合
- 解決方法2:不要な属性をtools:removeで削除する
- 解決方法3:不要な要素をtools:node=”remove”で削除する
- 原因2:android:exportedが競合している
- 原因3:ライブラリのminSdkVersionが高い
- uses-sdkのoverrideLibraryを使用する場合
- 原因4:ライブラリを追加した直後に発生した
- 原因5:debugやflavor用Manifestとの競合
- Manifestの優先順位を確認する
- Manifest Mergerのログを確認する
- tools名前空間を追加していない場合
- 修正後に再ビルドする
- それでもManifest merger failedが直らない場合
- まとめ
Manifest merger failedとは
Androidアプリでは、
最終的にAPKやAndroid App Bundleへ含まれる
AndroidManifest.xmlは1つです。
しかし、Android Studioのプロジェクト内では、
アプリ本体だけでなく、
ビルドタイプ、Product Flavor、導入しているライブラリなどが
それぞれManifestを持っている場合があります。
ビルド時にはこれらのManifestが自動的に1つへ統合されます。
この処理がManifest Mergeです。
複数のManifestに同じ要素や属性があり、
それぞれ異なる値が指定されていて自動的に統合できない場合、
Manifest merger failedが発生します。
ポイント:
Manifest merger failedは、
AndroidManifest.xmlそのものが必ず壊れているという意味ではありません。
導入しているライブラリ側のManifestと、
アプリ側のManifestが競合している場合にも発生します。
代表的なエラー表示
Manifest merger failed : Attribute application@theme
value=(@style/AppTheme)
from AndroidManifest.xml
is also present at AndroidManifest.xml
value=(@style/AnotherTheme).
このような場合、
application要素の
android:themeに対して、
複数のManifestから異なる値が指定されています。
実際のエラーでは、
theme以外にも、
android:exported、
android:label、
android:allowBackup、
minSdkVersionなど、
さまざまな属性で競合が発生することがあります。
まずMerged Manifestを確認する
Manifest merger failedが発生した場合、
最初に確認したいのがAndroid Studioの
Merged Manifestです。
- Android Studioで
AndroidManifest.xmlを開きます。 - エディタ下部の
Merged Manifestを開きます。 - 競合している項目を確認します。
- どのManifestからその設定が追加されているか確認します。
Merged Manifestでは、
アプリ本体だけでなく、
ライブラリなどから追加されたManifestの内容も確認できます。
競合が発生している場合は
Merging Errorsに内容が表示され、
どの属性が競合しているかを確認できます。
Manifestの各要素がどこから追加されたものなのかも確認できるため、
まずここで競合元を特定することが重要です。
原因1:同じ属性に異なる値が設定されている
最も代表的なのが、
アプリ側とライブラリ側で同じ属性に異なる値が設定されているケースです。
たとえばアプリ側のManifestが次のようになっているとします。
<application
android:theme="@style/AppTheme">
一方、別のManifestでは次のようになっている場合があります。
<application
android:theme="@style/LibraryTheme">
同じandroid:themeに異なる値が指定されているため、
Manifest Mergerがどちらを採用すればよいか判断できず、
エラーになる場合があります。
解決方法1:tools:replaceでアプリ側の値を使用する
アプリ側の設定を優先したい場合は、
tools:replaceを使用して、
指定した属性をアプリ側の値で置き換えることができます。
まず、
<manifest>に
tools名前空間を追加します。
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
そのうえで、
競合している属性に
tools:replaceを指定します。
<application
android:theme="@style/AppTheme"
tools:replace="android:theme">
これにより、
android:themeについては
優先度の高いアプリ側Manifestの値を使用するよう指定できます。
注意:
エラーが出たからという理由だけで
tools:replaceを追加するのではなく、
どちらの設定を使用するべきか確認してから指定してください。
ライブラリが必要としている設定を誤って上書きすると、
ビルドできてもアプリの動作に影響する可能性があります。
複数の属性をtools:replaceで指定する場合
複数の属性が競合している場合は、
カンマ区切りで指定できます。
<application
android:theme="@style/AppTheme"
android:allowBackup="false"
tools:replace="android:theme,android:allowBackup">
この例では、
android:themeと
android:allowBackupについて、
アプリ側の設定を優先します。
解決方法2:不要な属性をtools:removeで削除する
ライブラリなどから追加される属性自体が不要な場合は、
tools:removeを使用できます。
<application
tools:remove="android:allowBackup">
指定した属性をマージ結果から取り除くために使用します。
複数の属性を削除する場合は、
tools:replaceと同様にカンマ区切りで指定できます。
解決方法3:不要な要素をtools:node=”remove”で削除する
属性ではなく、
ライブラリから追加される
activity、
service、
providerなどの要素そのものを削除したい場合は、
tools:node="remove"を使用できます。
<activity
android:name="com.example.SomeActivity"
tools:node="remove" />
これにより、
マージ対象となるManifestに存在する該当要素を
マージ結果から削除できます。
ライブラリが動作するために必要な
activityやserviceなどを削除すると、
アプリの機能が正常に動作しなくなる可能性があります。
削除対象が本当に不要なのか確認してから使用します。
原因2:android:exportedが競合している
android:exportedも
Manifest Mergeで競合することがある属性です。
たとえば、
同じActivityについて一方では
true、
もう一方では
falseが指定されている場合、
競合する可能性があります。
<activity
android:name=".MainActivity"
android:exported="true"
tools:replace="android:exported">
アプリ側の設定を使用することが正しいと確認できた場合は、
このように
tools:replaceで指定できます。
原因3:ライブラリのminSdkVersionが高い
導入したライブラリが、
アプリで設定している
minSdkより高いAndroidバージョンを要求している場合にも、
Manifest Mergeの段階でエラーになることがあります。
uses-sdk:minSdkVersion 21 cannot be smaller than version 23 declared in library
この場合は、
まずアプリの
minSdkと、
使用しているライブラリが対応している最低Androidバージョンを確認します。
アプリ側の最低対応バージョンを上げても問題がない場合は、
モジュールのGradle設定で
minSdkを変更します。
android {
defaultConfig {
minSdk = 23
}
}
使用しているプロジェクトのGradle記述形式によっては、
設定方法が異なる場合があります。
minSdkを上げると、
それより古いAndroidバージョンの端末へ
アプリをインストールできなくなります。
単にエラーを消すためだけに変更せず、
アプリの対応OS範囲を確認してから変更します。
uses-sdkのoverrideLibraryを使用する場合
AndroidのManifest Mergeには、
ライブラリ側の高い
minSdk要求を上書きするための
tools:overrideLibraryもあります。
<uses-sdk
tools:overrideLibrary="com.example.library" />
ただし、
ライブラリが高いAndroidバージョンのAPIを実際に必要としている場合、
古いAndroid端末で実行時エラーが発生する可能性があります。
基本的には、
対応しているライブラリのバージョンを使用するか、
アプリ側の
minSdkを適切に変更する方法を先に検討します。
原因4:ライブラリを追加した直後に発生した
Manifest merger failedが
新しいライブラリを追加した直後に発生した場合は、
そのライブラリのManifestが原因である可能性があります。
この場合は、
Merged Manifestで
どのライブラリから競合している設定が追加されたのか確認します。
- 追加したライブラリを確認します。
Merged Manifestを開きます。- 競合している属性や要素を確認します。
- どのManifestが値を追加しているか確認します。
- 必要に応じてライブラリのバージョンやManifest設定を見直します。
原因5:debugやflavor用Manifestとの競合
Android Studioでは、
src/main/AndroidManifest.xmlだけでなく、
ビルドタイプやProduct Flavorごとに
別のManifestを使用できます。
たとえば次のようなManifestが存在する場合があります。
src/main/AndroidManifest.xml
src/debug/AndroidManifest.xml
src/release/AndroidManifest.xml
これらに同じActivityや属性が異なる内容で設定されていると、
Manifest Mergeで競合する場合があります。
特定のビルドバリアントだけでエラーが発生する場合は、
mainだけでなく、
debug、
release、
Product Flavor用のManifestも確認します。
Manifestの優先順位を確認する
Manifest Mergeでは、
すべてのManifestが同じ優先順位で扱われるわけではありません。
ビルドバリアント用Manifest、
ビルドタイプ用Manifest、
Product Flavor用Manifest、
メインManifest、
ライブラリのManifestなどが
優先順位に従って統合されます。
そのため、
エラーを解消するときは単純に
「同じ記述を削除する」のではなく、
どのManifestが優先されているのか確認することも重要です。
Manifest Mergerのログを確認する
Merged Manifestだけでは原因を判断しにくい場合は、
Manifest Mergerのログを確認できます。
マージ処理の詳細なレポートは、
モジュール内の次のディレクトリに生成されます。
build/outputs/logs/
この中にある
manifest-merger-ビルドバリアント-report.txt
形式のファイルを確認すると、
Manifestがどのように統合されたのか詳細を確認できます。
tools名前空間を追加していない場合
tools:replaceや
tools:removeを記述したにもかかわらず、
tools自体が認識されない場合は、
<manifest>に名前空間が宣言されているか確認します。
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:toolsがない状態では、
tools:replaceなどを使用できません。
修正後に再ビルドする
Manifestを修正したら、
再度アプリをビルドしてエラーが解消したか確認します。
Android Studioの
Buildから再ビルドし、
Build Outputに
Manifest merger failedが表示されなくなったか確認します。
エラーが残っている場合は、
最初の競合を解消したことで別の競合が表示されることもあるため、
新しく表示されたエラー内容も確認します。
それでもManifest merger failedが直らない場合
エラーが解消しない場合は、
エラーメッセージの
Attribute、
Element、
AndroidManifest.xmlの行番号、
競合しているライブラリ名などを確認します。
- Build OutputでManifest Mergeのエラー全文を確認します。
Merged Manifestを確認します。- 競合元のManifestを確認します。
- 同じ属性に異なる値が指定されていないか確認します。
- 追加したライブラリのManifestを確認します。
- debugやreleaseなど別のManifestも確認します。
- 必要に応じて
tools:replaceやtools:removeを使用します。 - ライブラリと
minSdkの互換性を確認します。
まとめ
Android Studioの
Manifest merger failedは、
複数のAndroidManifest.xmlを統合するときに
設定が競合している場合に発生するエラーです。
まず
Merged Manifestで競合しているManifestと属性を確認し、
アプリ側の設定を優先する必要がある場合は
tools:replace、
不要な属性や要素を削除する場合は
tools:removeや
tools:node="remove"などを使用します。
また、
ライブラリのminSdk、
ビルドバリアントごとのManifest、
新しく追加したライブラリなどが原因になる場合もあります。
Manifest merger failedでは、
エラーメッセージに表示される
「どの属性が」「どのManifestと競合しているのか」を確認することが
解決への最も重要な手順です。
原因を確認せずに
tools:replaceを追加するのではなく、
競合している設定の意味を確認したうえで修正します。
