Android 上的 SDK 相依性解決方案

相依性問題發生在共用套件或程式庫上,其中多個其他套件具有相依性,但相依於不同和不相容的共用套件版本。Gradle 讓 Android 開發人員能夠輕鬆應對,只需在 build.gradle 中新增一個相依性,就可以無縫地在建置中加入必要的程式庫。但是,當兩個相依性相依於不同版本的相同程式庫時,會發生什麼狀況呢?

如果兩個相依性屬於相同設定(即應用程式設定),Gradle 將能自動解決相依性問題。例如,Audience Network Android SDK 相依於「exoplayer」程式庫。如果您需要新增不同的「exoplayer」程式庫版本,Gradle 將選擇加入較新的版本。但是,如果兩個相依性屬於不同設定(即應用程式和測試),Gradle 將擲回錯誤。下面我們將介紹不同的衝突和解決方案。

必要條件

繼續操作前,請務必詳閱 Audience Network 新手指南Android 新手指南

相依性衝突

1:相同設定相依性中的共用程式庫

2:不同設定相依性中的共用程式庫

相依性衝突解決方案

1:讓 Gradle 自動解決相依性問題

2:排除特定版本的相依性

3:在 Gradle 中明確定義衝突的程式庫

4:程式庫強制解決



相依性衝突

1:相同設定相依性中的共用程式庫

請思考下列範例。以下程式碼中的兩個相依性皆保持相同的設定,並且對程式庫「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'  

2:不同設定相依性中的共用程式庫

如果兩個相依性屬於不同設定(即應用程式和測試設定),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' 

相依性衝突解決方案

1:讓 Gradle 自動解決

此方法是最簡單的方法,但僅限於相同設定中的相依性。例如,您的模組明確相依於特定版本的 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' 

2:排除特定版本的相依性

多數情況下,開發人員可能希望控制加入建置的最終程式庫版本。您可以設定 build.gradle 來這麼做。例如,如果開發人員偏好舊的 ExoPlayer r2.4.0 版而不是 Audience Network SDK 中的 r2.4.2 版,可以在宣告「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'
}

3:在 Gradle 中明確定義衝突的程式庫

此方法可以更簡潔解決不同設定相依性的衝突問題。在此情況下,我們需要明確指出程式庫的版本,其為我們希望在任何設定之一的最終建置中加入的版本。

此方法可以更簡潔解決衝突問題,但缺點是,在更新實際的相依性(例如 junitmockito)時,開發人員也需要更新衝突的程式庫。

// 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' 

4:程式庫強制解決

這是另一種解決衝突的方法,此方法不宣告單一設定,而是在所有設定下強制執行。在以下範例中,您可將自己的「resolutionStrategy」新增至模組層級 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'
    }
}

後續步驟

其他資源

新手指南

開始使用 Audience Network 的技術指南

API 參考資料

Facebook iOS SDK 參考資料