Как управлять различными версиями библиотеки поддержки для сторонних депов с градиентом?

У меня есть куча сторонних библиотек, которые я включаю в свое базовое приложение. Я не могу контролировать библиотеку поддержки, которую включают сторонние модули. Это затрудняет использование одной и той же версии библиотеки поддержки Android в моем приложении.

Я знаю использование gradle, когда я могу исключить определенные библиотеки из каждой зависимости:

compile('com.test:lib1:1.0.0') {
    exclude group: 'com.android.support'
}

Однако существует множество библиотек поддержки, и исключение их всех для каждой из моих сторонних библиотек кажется излишним.

Есть ли лучший способ?

Чтение этого блога: https://www.devsbedevin.net/android-understanding-gradle-dependencies-and-resolving-conflicts/

Он предлагает:

configurations.all {
  resolutionStrategy {
    preferProjectModules()
  }
}

Однако, используя его, я все равно получаю предупреждение в Android Studio в своем файле Gradle о том, что обнаружено несколько версий библиотеки поддержки.

Что мне делать, если мои зависимости зависят от разных версий библиотеки поддержки? В любом случае выше я бы заставил сторонние библиотеки использовать определенную версию библиотеки поддержки, с которой они не были собраны. Какую версию я должен использовать? Последняя библиотека поддержки? Минимальная библиотека поддержки всех сторонних зависимостей?

Вот минимальный пример файла Gradle, показывающий использование сторонних зависимостей, каждая из которых зависит от собственной версии библиотеки поддержки.

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    defaultConfig {
        applicationId "com.example.app"
        minSdkVersion 17
        targetSdkVersion 25
    }
}

configurations.all {
    resolutionStrategy {
        preferProjectModules()
    }
}

dependencies {
    compile 'com.android.support:support-v13:26.0.0'
    compile 'com.test:lib1:1.0' // depends on support-v13:25.0.0
    compile 'com.test:lib2:1.0' // depends on support-v13:25.2.0
    compile 'com.test:lib3:1.0' // depends on support-v13:25.4.0
    compile 'com.test:lib4:1.0' // depends on support-v13:26.0.0
}

Android-студия выдает следующее предупреждение:

enter image description here

Ответ 1

Это, безусловно, возможно. В ваших проектах build.gradle file (файл build.gradle верхнего уровня) добавьте следующий код:

ext {
    supportlib_version = '26.1.0'
    gps_version = '11.2.0'
}

//Ensure that all dependencies use the same version of the Android Support library
subprojects {
    project.configurations.all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == 'com.android.support'
                    && !details.requested.name.contains('multidex')) {
                details.useVersion "$supportlib_version"
            }
            if (details.requested.group == 'com.google.android.gms'
                    && !details.requested.name.contains('multidex')) {
                details.useVersion "$gps_version"
            }
        }
    }
}

Следующий код гарантирует, что версия зависимости com.android.support будет равна $ supportlib_version для всех зависимостей. То же самое для рамки com.google.android.gms.

Убедитесь, что в файле build.gradle модуля вы также используете эти версии для своих зависимостей. Например:

compile "com.android.support:support-v4:$supportlib_version"

Подробнее о форсировании определенной версии зависимостей в документации Official Gradle.

Обновление Google имеет развязанные версии библиотеки. Следовательно, принудительная версия версии выше 15.0.0 может не работать. Вместо этого вы можете разрешить ограниченный диапазон версий. Пример ниже позволяет использовать любую версию выше 15.0.0, но ниже 16.

gps_version = '[15.0.0, 16.0.0)'

Ответ 2

Первый случай: у вас есть совместимые библиотеки, которые уже обновили свои собственные внутренние библиотеки, здесь нет проблем.

Второй случай: у вас есть libs в вашем проекте, у которых более высокая версия, чем другие библиотеки, содержащиеся внутри других libs, и эти библиотеки могут быть обновлены до новой версии без такой проблемы. Также здесь нет проблем.

Худший случай: у вас есть libs в вашем проекте, которые имеют более высокую версию, чем другие библиотеки, содержащиеся внутри других libs, и эти библиотеки не имеют новой версии, которая уже обновила там внутренние библиотеки, предлагаемые решения для этого:

  1. Загрузите эту библиотеку и включите ее в свое приложение в качестве проекта implementation project(':library') и обновите свои внутренние implementation project(':library').
  2. ИЛИ Вместо этого используйте другую библиотеку.

Не забудьте использовать ./gradlew app:dependencies чтобы проверить ваши зависимости.

Также, я считаю, должен быть там, чтобы сделать это автоматически.

Ответ 3

Вам нужно указать зависимость, с вашей желаемой версией, которая вызывает конфликт перед libs, который в ней нуждается. Если вы это сделаете, эти lib будут использовать вашу указанную версию зависимостей.

Пример с libs (из предупреждающего сообщения) с вашего скриншота

dependencies {
    compile 'com.android.support:support-v13:26.0.0'
    compile 'com.android.support:support-compat:26.0.0'
    compile 'com.android.support:animated-vector-drawable:26.0.0'
    compile 'com.test:lib1:1.0' // depends on support-v13:25.0.0
    compile 'com.test:lib2:1.0' // depends on support-v13:25.2.0
    compile 'com.test:lib3:1.0' // depends on support-v13:25.4.0
    compile 'com.test:lib4:1.0' // depends on support-v13:26.0.0
}

Продолжайте добавлять зависимости (которые отображаются в предупреждении с вашего снимка экрана) до тех пор, пока больше не будет предупреждающего сообщения о разных версиях библиотеки.

Ответ 4

Сделать targetsdkversion 26, а также в вашем Gradle внести изменения в 26 или и может изменить вашу compilesdk версию 25 и изменить соответствующие dependecies 25