공유 패키지나 라이브러리에서 여러 가지 패키지에 종속성이 있지만 공유 패키지의 서로 다르고 호환되지 않는 버전에 종속되는 경우에는 종속성 이슈가 발생합니다. Gradle의 경우 build.gradle에 종속성 하나만 추가하면 필수 라이브러리가 빌드에 매끄럽게 포함되므로 Android 개발자의 삶을 더욱 편리하게 해줍니다. 하지만 두 개의 종속성이 동일한 라이브러리의 서로 다른 버전에 종속성을 가지고 있다면 어떻게 될까요?
Gradle은 두 종속성이 동일한 구성(즉, 앱 구성)에 속하는 경우 종속성을 자동으로 해결할 수 있습니다. 예를 들어 Audience Network Android SDK는 "exoplayer" 라이브러리에 종속됩니다. 다른 버전의 "exoplayer" 라이브러리를 추가해야 할 경우 Gradle이 더 높은 버전을 선택하여 포함합니다. 하지만 두 종속성이 서로 다른 구성(즉, 앱과 테스트)에 속하는 경우 Gradle이 오류를 발생시킵니다. 아래에서 여러 가지 충돌과 해결책을 살펴볼 것입니다.
계속하기 전에 Audience Network 시작하기 및 Android 시작하기 가이드를 완료했는지 확인하세요.
다음의 예시를 고려해 보세요. 아래 코드에 있는 두 종속성은 동일한 구성에 속하고 "org.hamcrest:hamcrest-core" 라이브러리에 내부 종속성이 있습니다. 두 종속성이 내부적으로 동일한 라이브러리의 서로 다른 버전을 사용하므로 최상위 버전이 빌드에 포함됩니다. Gradle 동기화의 결과를 보면, 최종 빌드에서 hamcrest 라이브러리 버전이 1.1에서 1.3으로 자동 업그레이드되는 것으로 명확히 나와 있습니다.
// Depends on version 1.3 of org.hamcrest:hamcrest-core androidTestImplementation 'junit:junit:4.12' // Depends on version 1.1 of org.hamcrest:hamcrest-core androidTestImplementation 'org.mockito:mockito-core:1.10.19'
두 종속성이 서로 다른 구성(예: 앱과 테스트 구성)에 속하는 경우 Gradle이 오류를 발생시킬 것입니다. 다음의 픽셀 코드를 고려해 보세요. 첫 번째 종속성이 앱 구성에 속하고 두 번째 종속성이 테스트 구성에 속합니다. 그러므로 프로젝트를 빌드하면 예외가 발생하며 실패하게 됩니다.
계측 테스트를 실행하면 메인 APK와 테스트 APK가 동일한 클래스 경로를 공유합니다. 메인 APK 및 테스트 APK가 동일한 라이브러리(예: Guava)를 사용하지만 버전이 서로 다른 경우에는 Gradle 빌드가 실패합니다. Gradle에서 실패를 탐지하지 못하면 앱이 테스트와 정상 실행 중에 다르게 동작할 수 있습니다(테스트와 정상 실행 중 충돌하는 경우 포함).
// Depends on version 1.3 of org.hamcrest:hamcrest-core implementation 'junit:junit:4.12' // Depends on version 1.1 of org.hamcrest:hamcrest-core androidTestImplementation 'org.mockito:mockito-core:1.10.19'
이 접근 방법은 가장 간단하지만 동일한 구성 내에 있는 종속성으로 제한됩니다. 예를 들어 모듈이 ExoPlayer의 특정 버전에 명시적으로 종속되지만 Audience Network SDK가 이미 다른 버전의 ExoPlayer를 포함했다고 생각해 보세요. 기본적으로 최상위 버전이 빌드에 포함됩니다. 아래의 픽셀 코드에서 Gradle 동기화의 결과를 보면, 최종 빌드에서 ExoPlayer 라이브러리 버전이 r2.4.2에서 2.7.3으로 자동 업그레이드되는 것으로 명확히 나와 있습니다.
implementation 'com.google.android.exoplayer:exoplayer-core:2.7.3' implementation 'com.google.android.exoplayer:exoplayer-dash:2.7.3' ... // audience-network-sdk depends on exoplayer-core:r2.4.2 and exoplayer-dash:r2.4.2 implementation 'com.facebook.android:audience-network-sdk:4.28.1'
대부분의 경우, 개발자는 최종적으로 빌드에 포함할 라이브러리 버전을 통제하고자 할 수 있습니다. build.gradle을 구성하면 통제가 가능합니다. 예를 들어 개발자가 Audience Network SDK에서 r2.4.2 대신 ExoPlayer r2.4.0의 더 낮은 버전을 선호한다면 "audience-network-sdk" 종속성을 선언할 때 해당 모듈을 제외할 수 있습니다. 제외 태그는 다른 구성에 있는 종속성에도 적용됩니다.
실제 프로젝트에서는 동일한 라이브러리의 서로 다른 버전이 있는 종속성이 많을 것입니다. 이 경우 각각의 종속성에 대해 제외 태그를 달아서 해당 라이브러리의 예상 버전을 포함할 수 있습니다.
시나리오 1: 동일한 구성의 종속성implementation 'com.google.android.exoplayer:exoplayer-core:r2.4.0' implementation 'com.google.android.exoplayer:exoplayer-dash:r2.4.0' ... // audience-network-sdk depends on exoplayer-core:r2.4.2 and exoplayer-dash:r2.4.2 implementation ('com.facebook.android:audience-network-sdk:4.28.1') { exclude group: 'com.google.android.exoplayer', module:'exoplayer-core' exclude group: 'com.google.android.exoplayer', module:'exoplayer-dash' }시나리오 2: 서로 다른 구성의 종속성
// Depends on version 1.3 of org.hamcrest:hamcrest-core implementation 'junit:junit:4.12' // Depends on version 1.1 of org.hamcrest:hamcrest-core androidTestImplementation ('org.mockito:mockito-core:1.10.19'){ exclude group: 'org.hamcrest', module:'hamcrest-core' }
이 방법은 서로 다른 구성에 있는 종속성의 충돌을 더욱 깔끔하게 해결할 수 있습니다. 이 경우, 서로 다른 구성 중 하나에 대해 최종 빌드에 포함하고자 하는 라이브러리의 버전을 명시적으로 언급해야 합니다.
이 접근 방법은 더욱 깔끔하게 충돌을 해결할 수는 있지만 junit, mockito와 같은 실제 종속성을 업데이트하는 동안 개발자가 충돌한 라이브러리도 업데이트해야 한다는 단점이 있습니다.
// Depends on version 1.3 of org.hamcrest:hamcrest-core implementation 'junit:junit:4.12' // Depends on version 1.1 of org.hamcrest:hamcrest-core androidTestImplementation 'org.mockito:mockito-core:1.10.19' // Explictly mention that include version 1.3 of org.hamcrest:hamcrest-core androidTestCompile 'org.hamcrest:hamcrest-core:1.3'
이는 하나의 구성에 대해 선언하는 대신 충돌을 해결하는 또 다른 방법으로, 모든 구성에 대해 강제 적용합니다. 아래의 예시에서 자체적인 "resolutionStrategy"를 module level build.gradle에 추가하여 특정 버전의 패키지를 포함하도록 강제 적용합니다(이때 종속성이 동일한 구성에 있든 서로 다른 구성에 있든 무관).
이 접근 방법은 다소 주의해서 사용해야 합니다. 첫 번째 예시에서 audience-network-sdk가 업데이트되고 이러한 라이브러리가 exoplayer-core 및 exoplayer-dash 라이브러리의 버전을 업데이트하더라도 이전 버전을 사용하도록 강제 적용될 것입니다. 이 시나리오는 두 번째 해결 방법에도 동일하게 적용되지만, 이 경우에는 하나의 구성이 아니라 모든 구성에 종속성 버전이 강제 적용됩니다.
시나리오 1: 동일한 구성의 종속성android { configurations.all { resolutionStrategy.force 'com.google.android.exoplayer:exoplayer-core:r2.4.0' resolutionStrategy.force 'com.google.android.exoplayer:exoplayer-dash:r2.4.0' } }시나리오 2: 서로 다른 구성의 종속성
android { configurations.all { resolutionStrategy.force 'org.hamcrest:hamcrest-core:1.1' } }
앱에서 테스트 광고 통합
검수를 위해 앱을 제출합니다.
Facebook은 앱이나 웹사이트에서 광고 요청을 받는 즉시, 광고 요청이 Audience Network 정책 및 Facebook 커뮤니티 규정을 준수하는지 확인하기 위해 검수합니다. 검수 절차에 대해 자세히 알아보세요.