안드로이드 'Manifest merger failed with multiple errors' 오류 완벽 해결 가이드
안녕하세요.
이번 포스팅은 안드로이드 앱을 개발하다 보면 종종 마주치게 되는 "Manifest merger failed with multiple errors" 오류! 빌드 시 갑자기 나타나는 이 에러 메시지는 많은 개발자들을 당황스럽게 만들곤 합니다. 오늘은 이 오류의 원인과 다양한 해결 방법에 대해 상세히 알아보겠습니다.
목차
- Manifest merger failed 오류란?
- 주요 발생 원인
- 오류 해결 방법
- 라이브러리별 해결 사례
- Android Studio에서 충돌 확인하기
- 자주 묻는 질문 (FAQ)
- 요약 및 결론
#1. Manifest merger failed 오류란?
Manifest merger failed 오류는 안드로이드 프로젝트에서 여러 개의 AndroidManifest.xml 파일이 병합되는 과정에서 충돌이 발생할 때 나타납니다. 안드로이드 앱은 메인 프로젝트의 매니페스트 파일뿐만 아니라, 포함된 모든 라이브러리의 매니페스트 파일도 함께 병합하여 최종 매니페스트 파일을 생성합니다.
이 과정에서 다음과 같은 상황이 발생하면 병합 오류가 발생합니다:
- 동일한 요소에 대해 다른 속성값이 지정된 경우
- 호환되지 않는 SDK 버전 설정
- 중복된 권한이나 활동 선언
- 라이브러리 간 충돌
오류 메시지의 일반적인 형태는 다음과 같습니다:
Manifest merger failed with multiple errors, see logs |
#2. 주요 발생 원인
1) SDK 버전 충돌
가장 흔한 원인은 서로 다른 라이브러리가 요구하는 minSdkVersion
, targetSdkVersion
, compileSdkVersion
간의 충돌입니다.
예를 들어:
- 메인 앱:
minSdkVersion 21
- 라이브러리 A:
minSdkVersion 23
이런 경우 라이브러리가 요구하는 최소 SDK 버전이 앱의 설정보다 높아 충돌이 발생합니다.
2) 동일 태그의 속성 충돌
여러 매니페스트 파일에서 동일한 태그에 다른 속성값을 지정한 경우입니다.
예를 들어:
<!-- 앱의 매니페스트 --> <application android:allowBackup="true" ... /> <!-- 라이브러리의 매니페스트 --> <application android:allowBackup="false" ... /> |
3) 중복 권한 선언
동일한 권한이 여러 매니페스트 파일에 선언된 경우입니다.
4) 활동, 서비스, 리시버 등의 중복 선언
동일한 컴포넌트가 여러 매니페스트 파일에 중복 선언된 경우입니다.
5) tools 네임스페이스 부재
충돌 해결을 위한 tools
네임스페이스가 정의되지 않은 경우입니다.
#3. 오류 해결 방법
1) 로그 확인하기
첫 번째 단계는 자세한 오류 로그를 확인하는 것입니다. Android Studio의 Build 탭이나 Gradle Console에서 확인할 수 있습니다.
2) tools 네임스페이스 추가
매니페스트 파일에 tools
네임스페이스를 추가합니다:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="cohttp://m.example.myapp"> |
3) 충돌 해결을 위한 tools:replace 사용
충돌하는 속성을 재정의하려면 tools:replace
를 사용합니다:
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" tools:replace="android:allowBackup"> |
4) tools:node 지시어 사용
특정 요소의 병합 방식을 지정하려면 tools:node
지시어를 사용합니다:
tools:node="remove"
: 요소 제거tools:node="removeAll"
: 모든 하위 요소 제거tools:node="merge"
: 기본 병합 동작 (명시적)tools:node="replace"
: 요소 교체
예시:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" /> |
5) build.gradle 파일에서 충돌 처리
build.gradle
파일에서도 매니페스트 병합 충돌을 처리할 수 있습니다:
android { defaultConfig { // 기타 설정들... // 매니페스트 병합 옵션 manifestPlaceholders = [hostName: "example.com"] // 매니페스트 병합 충돌 해결 manifestMerger = 'strict' // 또는 'auto', 'merge', 'legacyMerge' } // 매니페스트 병합 충돌 옵션 packagingOptions { merge 'META-INF/DEPENDENCIES' exclude 'META-INF/LICENSE' } } |
6) 라이브러리 버전 조정
충돌하는 라이브러리의 버전을 호환되는 버전으로 조정합니다:
dependencies { // 예시: Firebase 라이브러리 버전 명시 implementation 'com.google.firebase:firebase-core:20.0.0' implementation 'com.google.firebase:firebase-analytics:20.0.0' } |
7) 강제 병합 옵션 사용
심각한 충돌의 경우 강제 병합 옵션을 사용할 수 있습니다:
android { defaultConfig { // 기타 설정들... manifestPlaceholders = [hostName: "example.com"] } configurations.all { resolutionStrategy { force 'androidx.core:core:1.6.0' // 다른 강제 버전 지정 } } } |
#4. 라이브러리별 해결 사례
자주 매니페스트 병합 충돌을 일으키는 라이브러리들과 그 해결 방법을 살펴보겠습니다.
Firebase 라이브러리
Firebase 관련 라이브러리 간 충돌 시:
dependencies { // Firebase 라이브러리 버전 통일 implementation platform('com.google.firebase:firebase-bom:30.0.0') implementation 'com.google.firebase:firebase-analytics' implementation 'com.google.firebase:firebase-messaging' } |
Google Play Services
dependencies { // Google Play Services 버전 통일 implementation 'cohttp://m.google.android.gms:play-services-auth:20.0.0' implementation 'cohttp://m.google.android.gms:play-services-maps:18.0.0' } |
AndroidX 라이브러리
android { defaultConfig { // AndroidX 충돌 해결 vectorDrawables.useSupportLibrary = true } } dependencies { implementation 'androidx.core:core:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.0' } |
#5. Android Studio에서 충돌 확인하기
Android Studio에서는 매니페스트 병합 충돌을 쉽게 확인할 수 있는 도구를 제공합니다.
- Merged Manifest 탭 확인
- AndroidManifest.xml 파일을 열고 하단의 "Merged Manifest" 탭을 클릭합니다.
- 이 탭에서는 최종 병합된 매니페스트와 함께 경고 및 오류를 하이라이트하여 보여줍니다.
- Gradle sync 로그 확인
- Gradle sync 실행 후 발생한 오류 로그를 확인합니다.
- 로그에는 충돌이 발생한 정확한 위치와 원인을 표시합니다.
- 빌드 변형 확인
- 여러 빌드 변형(예: debug, release)이 있는 경우, 각 변형별로 매니페스트 병합 결과가 달라질 수 있습니다.
- Build Variants 패널에서 다른 변형을 선택하여 확인해보세요.
#6. 자주 묻는 질문 (FAQ)
Q: 'tools:replace'와 'tools:node="replace"'의 차이점은 무엇인가요?
A: tools:replace
는 특정 속성만 대체하는 반면, tools:node="replace"
는 전체 요소를 대체합니다. 예를 들어, tools:replace="android:icon,android:label"
은 icon과 label 속성만 대체하지만, tools:node="replace"
는 전체 태그를 대체합니다.
Q: 여러 라이브러리에서 동일한 권한을 요구할 때 어떻게 해야 하나요?
A: 이 경우 일반적으로 충돌이 발생하지 않습니다. 안드로이드 시스템은 동일한 권한이 여러 번 선언되더라도 중복을 자동으로 처리합니다. 하지만 문제가 발생한다면 tools:node="merge"
를 사용하여 명시적으로 병합을 지정할 수 있습니다.
Q: 매니페스트 병합 문제를 미리 예방하는 방법이 있나요?
A: 다음과 같은 방법으로 예방할 수 있습니다:
- 프로젝트의 모든 라이브러리 버전을 최신 상태로 유지
- 의존성 관리를 위한 BOM(Bill of Materials) 사용
- 라이브러리 사용 시 공식 문서의 권장 사항 준수
- 정기적인 Gradle 캐시 정리 (
./gradlew clean
)
Q: "Manifest merger failed: Attribute X has different values" 오류는 어떻게 해결하나요?
A: 이 오류는 동일한 속성에 다른 값이 지정되었을 때 발생합니다. 해결 방법:
tools:replace="속성명"
추가- 충돌하는 라이브러리 버전 통일
- 필요한 경우
tools:overrideLibrary
사용
#7. 요약 및 결론
"Manifest merger failed" 오류는 안드로이드 개발 시 흔히 마주치는 문제지만, 오류 로그를 잘 분석하고 적절한 해결 방법을 적용하면 쉽게 해결할 수 있습니다.
주요 해결 방법을 요약하면:
- 오류 로그 철저히 분석하기
- tools 네임스페이스 추가하기
- tools:replace, tools:node 등의 지시어 활용하기
- build.gradle에서 라이브러리 버전 조정하기
- Android Studio의 Merged Manifest 탭 활용하기
이런 오류 해결 과정은 단순히 문제를 해결하는 것을 넘어, 안드로이드 앱의 구조와 빌드 프로세스에 대한 이해를 높이는 좋은 기회가 됩니다. 매니페스트 병합 메커니즘을 이해하면 더 효율적인 앱 개발이 가능해집니다.
안드로이드 개발을 하시면서 매니페스트 병합 오류로 어려움을 겪고 계신다면, 이 글에서 소개한 방법들을 차근차근 적용해보세요. 대부분의 경우 오류를 해결할 수 있을 것입니다.
긴 글 읽어주셔서 감사합니다.
끝.
참고 자료: