Как и многие другие, я пытаюсь создать один файл AAR из своего многомодульного проекта Android.
Согласно этой публикации, в настоящее время не поддерживается командой Android из-за различных ограничений (управление разрешением и зависимостями, слияние манифестов, ...).
Я пытаюсь придумать свое собственное решение, которое будет соответствовать моим потребностям. Я знаю, что у меня нет дублированных ресурсов, а внешние зависимости (например, библиотеки поддержки) предоставляются людьми, использующими мою библиотеку.
Моя структура похожа на эту:
/root
|- lib1
|- lib2
|- lib3
Для достижения своей цели я создал еще один библиотечный модуль с именем distribute
, который будет включать в себя все остальные модули. Затем я могу поделиться сгенерированным файлом distribute.aar
.
/root
|- lib1
|- lib2
|- lib3
|- distribute
Это файл build.gradle
модуля distribute
:
apply from: '../common.gradle' // This simply configure properties shared accross all modules
apply plugin: 'com.android.library'
def allModules = rootProject.allprojects.collect { it.name } - [rootProject.name, name]
def whiteLabelDependencies = [
whiteLabel1: allModules - ['lib2'],
whiteLabel2: allModules,
]
android {
def buildTypeNames = buildTypes.collect { it.name }
def whiteLabelTypes = productFlavors.findAll { 'type'.equals(it.dimension) }.collect { it.name }
whiteLabelDependencies.each { whiteLabel ->
def modules = whiteLabel.value
def whiteLabelName = whiteLabel.key
whiteLabelTypes.each { whiteLabelType ->
def productFlavor = whiteLabelName + whiteLabelType.capitalize()
buildTypeNames.each { buildType ->
def sourceSet = productFlavor + buildType.capitalize()
def folders = ['main', whiteLabelName, whiteLabelType, productFlavor, whiteLabelName + buildType.capitalize(), sourceSet]
android.sourceSets.maybeCreate(sourceSet)
android.sourceSets.getByName(sourceSet) {
assets.srcDirs = getPathsList(modules, folders, 'assets')
java.srcDirs = getPathsList(modules, folders, 'java')
res.srcDirs = getPathsList(modules, folders, 'res')
resources.srcDirs = getPathsList(modules, folders, 'resources')
}
}
}
}
}
afterEvaluate {
whiteLabelDependencies.each { whiteLabel ->
def assembleTask = rootProject.tasks.getByPath(":${name}:assemble${whiteLabel.key.capitalize()}")
assembleTask.dependsOn whiteLabel.value.collect { ":${it}:assemble${whiteLabel.key.capitalize()}" }
}
}
dependencies {
whiteLabelDependencies.each { whiteLabel ->
whiteLabel.value.each {
"${whiteLabel.key}Compile" project(path: ":${it}", configuration: project.whiteLabelConfigurationName)
}
}
}
def List<File> getPathsList(List<String> modules, List<String> folders, String sourceType) {
return modules.collect { module ->
folders.collect { folder ->
new File("${rootProject.rootDir}/${module}/src/${folder}/${sourceType}")
}.findAll {
it.exists()
}
}.flatten()
}
Кажется, это почти работает, за исключением того, что во время выполнения происходит сбой приложения, потому что оно не может найти класс R
каждого модуля libx
, а только один из модуля distribute
. Есть ли способ заставить Gradle включать класс R
каждого модуля.
Я знаю, что файл для каждого модуля создается в $module/build/generated/source/r/$whiteLabel/$buildType/$package/$module/R.java
, но я не знаю, как его включить и предотвратить дублирование классов (каждый модуль может зависеть от другого).
libX/R.class
классы объединены в одинdistribute/R.class
? - person naXa   schedule 28.06.2016lib
имеет свой собственный классR
, потому что каждый модуль имеет свой собственный пакет (я думаю, это ограничение/требование плагина Android Gradle). Последний классdistribute/R
содержит все необходимые поля, но каждый модуль импортирует свой собственный классR
. - person Gaëtan   schedule 28.06.2016distribute/R
во время сборки. - person naXa   schedule 28.06.2016