如何使用Gradle的依赖树来解决Android支持库版本不匹配问题?

8

The Catalyst

我升级了Android Studio到2.3,Gradle插件到3.3。

The Initial Problem

在将Gradle插件更新为3.3之后,我收到错误提示:“Error:The SDK Build Tools revision (23.0.3) is too low for project ':mymodulename'. Minimum required is 25.0.0”。

我试着将buildToolsVersion和compileSdkVersion都调整到25.0.2及其以上版本,并且将所有com.android.support依赖项(因为它们的主要版本需要与compileSdkVersion匹配)也调整到25.0.2及其以上版本。这一调整解决了问题,但随后我发现我的应用程序还不支持Nougat系统,所以我将compileSdkVersion降回到了我的目标sdk版本23。关于构建工具版本太低的错误消息已经消失,因此我认为问题已经解决了。

The First Dependency Error

将编译版本号降至23后,我尝试重新构建,但看到了一些类似于“Error:(3) Error retrieving parent for item: No resource found that matches the given name 'android:TextAppearance.Material.Widget.Button.Borderless.Colored'” 的错误。我意识到我忘了将我的com.android.support依赖项更改为匹配较低的compileSdkVersion的主要版本,因此我将它们降至23.3.0。

The Second Dependency Error

解决了第一个依赖错误后,我又可以编译和运行我的应用程序了。然而,我的第一个com.android.support依赖项仍然有一个红色的波浪线,并显示错误说明“所有的com.android.support库必须使用完全相同的版本规范(混合版本可能会导致运行时崩溃)。发现版本24.0.0, 23.3.0。例如com.android.support:support-v4:24.0.0和com.android.support:animated-vector-drawable:23.3.0”。

我的build.gradle中没有特别指定使用24.0.0,请看:

apply plugin: 'com.android.application'


android {
    compileSdkVersion 23
    buildToolsVersion '25.0.2'


    defaultConfig {
        applicationId ...
        minSdkVersion 16
        targetSdkVersion 23
        versionCode ...
        versionName ...
    }
    buildTypes {
        debug{
            debuggable true
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    lintOptions{

        //check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
    dexOptions{
        jumboMode true
    }

}

repositories {
    // You can also use jcenter if you prefer
    mavenCentral()
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    //android support libs etc.
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:support-v13:23.3.0'
    compile 'com.android.support:mediarouter-v7:23.3.0'
    compile 'com.android.support:recyclerview-v7:23.3.0'
    //snackbar support
    compile 'com.android.support:design:23.3.0'

    //Facebook Android SDK
    compile 'com.facebook.android:facebook-android-sdk:4.7.0'
    //Facebook Audience Network SDK. Only versions 4.6.0 and above are available
    compile 'com.facebook.android:audience-network-sdk:4.7.0'

    //gplay services dependencies
    compile 'com.google.android.gms:play-services-plus:10.0.1'
    compile 'com.google.android.gms:play-services-analytics:10.0.1'
    compile 'com.google.android.gms:play-services-location:10.0.1'

    //provides Firebase Analytics
    compile 'com.google.firebase:firebase-core:10.0.1'

    //provides Google Mobile Ads SDK, a.k.a the AdMob service.
    compile 'com.google.firebase:firebase-ads:10.0.1'

    //dependencies required by the InMobi ads SDK
    compile 'com.squareup.picasso:picasso:2.5.2'

}

apply plugin: 'com.google.gms.google-services'

依赖树

为了找出24.0.0依赖是从哪里来的,我使用'./gradlew -q dependencies mymodulename:dependencies --configuration compile'命令创建了一个依赖树。输出结果如下:

    compile - Classpath for compiling the main sources.
+--- com.android.support:appcompat-v7:23.3.0
|    +--- com.android.support:support-vector-drawable:23.3.0
|    |    \--- com.android.support:support-v4:23.3.0 -> 24.0.0
|    |         \--- com.android.support:support-annotations:24.0.0
|    +--- com.android.support:animated-vector-drawable:23.3.0
|    |    \--- com.android.support:support-vector-drawable:23.3.0 (*)
|    \--- com.android.support:support-v4:23.3.0 -> 24.0.0 (*)
+--- com.android.support:support-v13:23.3.0
|    \--- com.android.support:support-v4:23.3.0 -> 24.0.0 (*)
+--- com.android.support:mediarouter-v7:23.3.0
|    +--- com.android.support:appcompat-v7:23.3.0 (*)
|    \--- com.android.support:palette-v7:23.3.0
|         \--- com.android.support:support-v4:23.3.0 -> 24.0.0 (*)
+--- com.android.support:design:23.3.0
|    +--- com.android.support:appcompat-v7:23.3.0 (*)
|    +--- com.android.support:support-v4:23.3.0 -> 24.0.0 (*)
|    \--- com.android.support:recyclerview-v7:23.3.0
|         +--- com.android.support:support-v4:23.3.0 -> 24.0.0 (*)
|         \--- com.android.support:support-annotations:23.3.0 -> 24.0.0
+--- com.facebook.android:facebook-android-sdk:4.7.0
|    +--- com.parse.bolts:bolts-android:1.2.0
|    \--- com.android.support:support-v4:[22,23) -> 24.0.0 (*)
+--- com.facebook.android:audience-network-sdk:4.7.0
|    \--- com.google.android.gms:play-services-ads:7.8.0 -> 10.0.1
|         +--- com.google.android.gms:play-services-ads-lite:10.0.1
|         |    \--- com.google.android.gms:play-services-basement:10.0.1
|         |         \--- com.android.support:support-v4:24.0.0 (*)
|         +--- com.google.android.gms:play-services-base:10.0.1
|         |    +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|         |    \--- com.google.android.gms:play-services-tasks:10.0.1
|         |         \--- com.google.android.gms:play-services-basement:10.0.1 (*)
|         +--- com.google.android.gms:play-services-clearcut:10.0.1
|         |    +--- com.google.android.gms:play-services-base:10.0.1 (*)
|         |    \--- com.google.android.gms:play-services-basement:10.0.1 (*)
|         +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|         \--- com.google.android.gms:play-services-gass:10.0.1
|              \--- com.google.android.gms:play-services-basement:10.0.1 (*)
+--- com.google.android.gms:play-services-plus:10.0.1
|    +--- com.google.android.gms:play-services-base:10.0.1 (*)
|    \--- com.google.android.gms:play-services-basement:10.0.1 (*)
+--- com.google.android.gms:play-services-analytics:10.0.1
|    +--- com.google.android.gms:play-services-analytics-impl:10.0.1
|    |    +--- com.google.android.gms:play-services-base:10.0.1 (*)
|    |    \--- com.google.android.gms:play-services-basement:10.0.1 (*)
|    +--- com.google.android.gms:play-services-base:10.0.1 (*)
|    +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|    \--- com.google.android.gms:play-services-tagmanager-v4-impl:10.0.1
|         +--- com.google.android.gms:play-services-analytics-impl:10.0.1 (*)
|         +--- com.google.android.gms:play-services-base:10.0.1 (*)
|         \--- com.google.android.gms:play-services-basement:10.0.1 (*)
+--- com.google.android.gms:play-services-location:10.0.1
|    +--- com.google.android.gms:play-services-base:10.0.1 (*)
|    +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|    \--- com.google.android.gms:play-services-tasks:10.0.1 (*)
+--- com.google.firebase:firebase-core:10.0.1
|    \--- com.google.firebase:firebase-analytics:10.0.1
|         +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|         +--- com.google.firebase:firebase-common:10.0.1
|         |    +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|         |    \--- com.google.android.gms:play-services-tasks:10.0.1 (*)
|         \--- com.google.firebase:firebase-analytics-impl:10.0.1
|              +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|              +--- com.google.firebase:firebase-iid:10.0.1
|              |    +--- com.google.android.gms:play-services-basement:10.0.1 (*)
|              |    \--- com.google.firebase:firebase-common:10.0.1 (*)
|              \--- com.google.firebase:firebase-common:10.0.1 (*)
+--- com.google.firebase:firebase-ads:10.0.1
|    +--- com.google.android.gms:play-services-ads:10.0.1 (*)
|    \--- com.google.firebase:firebase-analytics:10.0.1 (*)
+--- com.squareup.picasso:picasso:2.5.2
\--- com.android.support:recyclerview-v7:23.3.0 (*)

(*) - dependencies omitted (listed previously)

问题

  1. 依赖树语法中的“lib version -> different lib version”是什么意思?特别是,当树形结构显示“com.android.support:support-v4:23.3.0 -> 24.0.0”时,这代表什么?

  2. 如果我的其他依赖项中存在对com.android.support版本24.x.x库的隐式要求(例如com.google.android.gms:play-services-basement:10.0.1依赖于com.android.support:support-v4:24.0.0),为什么在Android Studio、Gradle插件和buildToolsVersion更新之前,该build.gradle没有抛出错误?

  3. 如何确保所有的依赖项都与compileSdkVersion 23兼容?


如果您使用版本23的支持库进行编译,但是却使用了版本25的支持库会发生什么? - Code-Apprentice
1
你应该将依赖树发布为文本。选择它并按Ctrl-K以保留格式。这个键盘快捷键添加了代码块所需的四个空格。 - Code-Apprentice
2
请记住,compileSdkVersion 不会改变您的应用程序行为 - 如 此博客文章 所解释的那样,这将由 targetSdkVersion 控制。即使您不针对最新版本进行开发,也应始终使用最新版本的 Android 进行编译。 - ianhanniballake
@Code-Apprentice 如果我针对25进行编译并使用支持库的23版本,我可以无错误地编译,但Gradle会用愤怒的波浪线标记版本23的依赖项。悬停提示说:“此支持库不应使用与compileSdkVersion(25)不同的版本(23)”。 - CCJ
@CCJ - 这正是为什么 Lint 检查会使用您的 minSdkVersion 来检查您何时可以调用每个 API。任何超过您的 minSdkVersion 的内容都将被标记。 - ianhanniballake
显示剩余2条评论
1个回答

7
具体来说,当树形结构中出现“com.android.support:support-v4:23.3.0 -> 24.0.0”时,这是什么意思呢?
这意味着一个库使用了“com.android.support:support-v4:23.3.0”作为嵌套依赖项,但您只是使用了另一个更高版本的相同依赖项,即“com.android.support:support-v4:24.0.0”。换句话说,您的项目正在使用“com.android.support:support-v4:24.0.0”。
那么,为什么在前面提到Android Studio、Gradle插件和buildToolsVersion更新之前,这个build.gradle没有抛出错误呢?
因为您已经将Gradle插件更新到了3.3,该插件具有此类检查功能。
如何确保所有依赖关系都与compileSdkVersion 23兼容呢?
这很困难。唯一的方法是检查所有依赖项,但我建议您使用:
compileSdkVersion 25
targetSdkVersion  23

一般来说,无论使用哪个版本的支持库,使用最新的buildToolsVersion版本都是一个好主意。

此外,强烈建议您始终使用最新的SDK进行编译。这意味着今天您应该使用compileSdkVersion 25。


好的,非常有趣。我尝试了一下我的其他依赖项,发现 com.google.android.gms 和 com.google.firebase 条目是引入 24.x.x 支持库版本的原因;将 com.google.android.gms 和 com.google.firebase 条目降级到 9.0.0 版本,就可以让支持库 23.x.x 和 compileSdkVersion 23 在没有错误标注的情况下正常工作。 - CCJ
关于您的编译最新SDK的评论,这不会冒险使用在我的目标API级别中不可用的新API吗? Lint可能会捕获它们,但不会有编译错误,我很确定会有运行时错误...使用比目标SdkVersion更高的compileSdkVersion有什么好处?您是否有官方参考建议开发人员始终使用最新的SDK版本进行编译? - CCJ
@CCJ 请查看此链接:https://medium.com/google-developers/picking-your-compilesdkversion-minsdkversion-targetsdkversion-a098a0341ebd#.23i9y3s6f。作者是Google的Android开发者倡导者:特别是要注意这部分:“应强调的是,更改您的compileSdkVersion不会改变运行时行为。虽然更改compileSdkVersion可能会出现新的编译器警告/错误,但您的compileSdkVersion不包含在您的APK中:它纯粹用于编译时。” - Gabriele Mariotti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接