Обучение мобильной разработке

Понять разрешение зависимостей Gradle проще

Упростите управление большим проектом Android с несколькими библиотеками с разными версиями одной и той же зависимости.

До Covid 19 (сейчас такая эра) ... Я рассказываю о том, как масштабировать мобильную разработку, в соответствии с приведенным ниже блогом.



Масштабирование мобильной разработки
Как мы можем практически масштабировать мобильную разработку? medium.com



С появлением Covid 19 масштабирование мобильной разработки становится еще более важным, все больше онлайн-транзакций и использования мобильных устройств продолжают расти.

Но есть одна проблема

Модель, о которой я рассказываю выше, выглядит следующим образом:

Но есть один сложный момент, с которым нам нужно справиться… всякий раз, когда мы представляем новое обновление для базового модуля, не все функциональные модули попадают в последний базовый модуль.

Следовательно, когда модуль координатора все компилирует, какая версия базового модуля будет решена?

Увидев эту проблему, важно изучить основы того, как Android Gradle разрешает конфликт зависимостей.

Примеры разрешения Gradle

Чтобы понять это, у меня есть очень простой проект, как показано ниже.

Разрешение зависимостей по умолчанию

Когда мы ничего не делаем, а просто включаем библиотеки, как показано ниже

implementation ('io.github.elye:easyandroidlibrary:3.0.0')
implementation ('io.github.elye:simpleandroidlibrary:2.0.0')
implementation ('io.github.elye:simplekotlinlibrary:1.0.0')

Это разрешит использование самой последней библиотеки, т. Е.

io.github.elye:simplekotlinlibrary:3.0.0

который будет применяться ко всем библиотекам

Разрешение зависимостей исключения

Но иногда мы хотим использовать только то, что включено в основное приложение, и игнорировать те, которые находятся в зависимых библиотеках, то есть игнорировать транзитивные зависимости одного и того же типа.

Мы можем использовать exclude, как показано ниже

implementation ('io.github.elye:easyandroidlibrary:3.0.0') {
    exclude group: 'io.github.elye', module: 'simplekotlinlibrary'
}
implementation ('io.github.elye:simpleandroidlibrary:2.0.0') {
    exclude group: 'io.github.elye', module: 'simplekotlinlibrary'
}
implementation ('io.github.elye:simplekotlinlibrary:1.0.0')

Здесь это заставит всех просто использовать то, что определено верхней библиотекой приложения, т.е.

io.github.elye:simplekotlinlibrary:1.0.0

который будет применяться ко всем библиотекам

Однако у этого подхода есть недостаток, так как нужно добавить exclude для всех библиотек, в которых есть SimpleKotlinLibrary.

Принудительное разрешение зависимостей

Другой подход - заставить использовать определенную библиотеку Top Module. Раньше это называлось force = true, но теперь (в Gradle 7.1.1) мы можем использовать вместо этого strictly, как показано ниже.

implementation ('io.github.elye:easyandroidlibrary:3.0.0')
implementation ('io.github.elye:simpleandroidlibrary:2.0.0')
implementation ('io.github.elye:simplekotlinlibrary') {
    version {
        strictly '1.0.0'
    }
}

При желании можно использовать ярлык с помощью !!, как показано ниже.

implementation ('io.github.elye:easyandroidlibrary:3.0.0')
implementation ('io.github.elye:simpleandroidlibrary:2.0.0')
implementation ('io.github.elye:simplekotlinlibrary:1.0.0!!')

Здесь это заставит всех просто использовать то, что определено верхней библиотекой приложения, т.е.

io.github.elye:simplekotlinlibrary:1.0.0

который будет применяться ко всем библиотекам

Этот подход намного лучше, чем exclude, поскольку не требует явного исключения из каждой библиотеки, в которой есть simplekotlinlibrary

Разрешение зависимостей ограничений

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

Мы можем использовать это constraint, как показано ниже

implementation ('io.github.elye:easyandroidlibrary:1.0.0')
implementation ('io.github.elye:simpleandroidlibrary:2.0.0')

constraints {
    implementation('io.github.elye:simplekotlinlibrary:3.0.0') {
        because 'force >= 3.0.0 for all transitive dependencies'
    }
}

Это приведет к тому, как показано ниже (обратите внимание, даже если используется библиотека версии 3, хотя все библиотеки изначально включают библиотеку ниже версии 3).

Следует отметить, что constraint ограничивает по крайней мере версию, которую он указывает. Следовательно, если библиотека включила SimpleKotlinLibrary с версией выше, чем версия constraint, тогда снова сработает обычное разрешение зависимостей по умолчанию, где самая высокая версия будет иметь приоритет.

например как показано ниже, это constraint в версии 3.0.0, но самая высокая зависимость перехода - версия 4.0.0, поэтому разрешенные зависимости по-прежнему simplekotlinlibrary:4.0.0.

implementation ('io.github.elye:easyandroidlibrary:4.0.0')
implementation ('io.github.elye:simpleandroidlibrary:2.0.0')

constraints {
    implementation('io.github.elye:simplekotlinlibrary:3.0.0') {
        because 'force >= 3.0.0 for all transitive dependencies'
    }
}

Надеюсь, вышеизложенное дает легкое фундаментальное понимание того, как можно легко управлять зависимостями. Это всего лишь несколько основных методов разрешения зависимостей, предоставляемых Gradle. Чтобы узнать о более сложных правилах, ознакомьтесь с



Кстати, если вам интересно, как это работает на iOS, посмотрите