Конфигурация Gradle с многомодульной андроидной библиотекой

Назад История

У меня есть эта андроидная библиотека, которую разработчики могут использовать обычно с помощью

 compile 'com.companyname.sdk:android-sdk:2.x' 

И теперь мы делаем перезапись библиотеки с нуля, чтобы создать V3.

В этой реорганизации нам удалось разбить lib на модули. Таким образом, можно сказать, что на V3 мы имели бы следующие артефакты

 compile 'com.companyname.sdk:core:3.x' compile 'com.companyname.sdk:extra_1:3.x' compile 'com.companyname.sdk:extra_2:3.x' compile 'com.companyname.sdk:extra_ .... 

И это придало бы структуре градиента следующие модули:

 root: |- test_app (apk just for testing, not deployed anywhere) |- sdk (aka: core) |- extra_1 |- extra_2 |- extra_ ... etc 

Для каждого extra модуля на их build.gradle есть provided (':sdk') так что он может использовать все из модуля sdk , но фактически не компилирует его внутри себя.

Но я также хотел бы обеспечить легкий путь миграции для существующих хост-приложений. Смысл, я бы хотел, чтобы на V3 также был следующий артефакт, который объединяет core и extra_1 (что в основном относится к V2).

 compile 'com.companyname.sdk:android-sdk:3.0.0' 

Все это звучит отлично по теории, но мне очень трудно понять, что такое структура градиента, которая позволяет мне легко экспортировать все это.

Что я хочу достичь

Поэтому я хотел бы иметь возможность во время сборки генерировать следующие артефакты:

  • android-sdk который включает как core и extra_1
  • core
  • extra_1
  • … все остальные дополнения

Что я пробовал?

  • Добавьте дополнительный модуль с именем legacy , примените com.android.library без какого-либо кода и добавьте compile project для обоих других модулей. Он генерирует пустой aar

  • Добавьте core / legacy buildTypes с исходными наборами из обоих модулей. Никогда не генерировал 2 aar

  • Добавить core / legacy productFlavours с исходными наборами из обоих модулей. Не компилируется, потому что он не может найти импорт из sdk , которые объявлены в extra_1 (некоторые из них генерируются во время обработчика аннотаций или lombok)

  • Добавить core / legacy productFlavours с compile project('extra_1') . Не компилируется, потому что существует циклическая зависимость между sdk и extra_1.

Ответ

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

Оговорка о подходе заключается в настройке плагина maven-publish . Обычно вам нужен объект publications с publications и узел pom.withXml . Мой был следующим:

  pom.withXml { def root = asNode() def license = root.appendNode('licenses').appendNode('license') license.appendNode('name', 'The Apache Software License, Version 2.0') license.appendNode('url', 'http://www.apache.org/licenses/LICENSE-2.0.txt') license.appendNode('distribution', 'repo') def dependenciesNode = asNode().appendNode('dependencies') configurations.compile.allDependencies.each { dependency -> def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', dependency.group) dependencyNode.appendNode('artifactId', dependency.name) dependencyNode.appendNode('version', dependency.version) } } 

Проблема с этим подходом заключается в том, что dependency.version (В конце) не указана, и как таковая она создает файл POM с <version>unspecified</version> .

Решение там просто, замените последнее с некоторой переменной u на скрипте с правильным номером версии. Мой выглядел так:

 dependencyNode.appendNode('version', "${rootProject.ext.SDK_VERSION}") 

Вы должны сделать что-то вроде этого:

 root: |- test_app (apk just for testing, not deployed anywhere) |- core |- extra_1 |- extra_2 |- extra_ ... etc |- android-sdk 

В core/build.gradle :

 apply plugin: 'com.android.library' //... 

В extra1/build.gradle :

 apply plugin: 'com.android.library' //... dependencies { compile project(':core') } 

В android-sdk/build.gradle :

 apply plugin: 'com.android.library' //... dependencies { compile project(':core') compile project(':extra') }