Ho un problema con la migrazione del mio progetto IDEA IntelliJ su Android Studio utilizzando una build gradle. Ho impostato la libreria AndroidAnnotations come consigliato in vari altri post e funziona perfettamente. Ma, quando si compila il mio progetto più volte senza eseguire il compito :clean
in mezzo, ricevo seguenti messaggi di errore:Gradle + AndroidAnnotation genera errori di classe duplicati: è necessario pulire il progetto prima di ogni generazione
/project-dir/build/source/apt_generated/flavor1/release/com/example/app/MyActivity_.java:15: error: duplicate class: com.example.app.MyActivity_
[more errors here...]
credo che più costruisce in serie falliscono perché AndroidAnnotations ricrea i file *_.java
sempre prima dei :compile
compiti (senza verificare se sia necessario o meno) e l'attività :compile
riconosce i nuovi file (ad esempio utilizzando la data/ora) ma li trova già come file *.class
precompilati, generando così l'errore. È possibile? Come posso prevenire questo comportamento? Posso aggiungere un controllo di necessità per AndroidAnnotations? Oppure questo è un altro problema?
UPDATE 1: Sembra che l'errore è gettato dal AndroidAnnotations stessa, dal momento :compile
opere quando elimino i file all'interno della cartella *.java
apt_generated
manualmente.
UPDATE 2:
ho tolto seguente riga dal mio build.gradle
:
// Automatically add the generated source code to the source set
android.sourceSets[getSourceSetName(variant)].java.srcDirs += aptOutput
io non so esattamente perché funziona senza questa linea. Dal momento che non ho aggiunto la cartella utilizzando Android Studio Mark Directory as > Sources Root
. Probabilmente questo è un risultato del caching? Oppure gradle in qualche modo aggiunge automaticamente i miei file java generati al classpath?
Sarei comunque grato per qualsiasi commento.
UPDATE 3/SOLUZIONE
Dopo aver rimosso la linea e sincronizzare il file di generazione Gradle con Android Studio, il codice sorgente generato automaticamente è stato rimosso come Source Root, causando l'IDE per mostrare gli errori di classi mancanti.
Alla fine, ho trovato la soluzione sulle questioni Android Annotazioni GitHub: https://github.com/excilys/androidannotations/issues/676
ho ri-aggiunge il comunicato per aggiungerlo ai set di origine (permettendo Android Studio per vederlo come root fonte). Inoltre, ho rimosso i file della collezione varianti fonte che utilizzano questo:
variant.javaCompile.source = variant.javaCompile.source.filter { p ->
return !p.getPath().startsWith(aptOutputDir.getPath())
}
Ora i file generati sono riconosciuti, e l'errore di classe duplicato è andato.
Con i migliori saluti, David
ecco la mia build.gradle finale.Spero che questo aiuta alcuni di voi:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
configurations {
// This is the annotations processor dependency configuration.
apt
}
def getSourceSetName(variant) {
return new File(variant.dirName).getName();
}
android {
compileSdkVersion 18
defaultConfig {
versionCode 10
versionName "1.0.2"
targetSdkVersion 17
minSdkVersion 10
}
buildToolsVersion "18.0.1"
buildTypes {
release {
zipAlign true
}
}
productFlavors {
flavor1 {}
flavor2 {}
}
// This has to go after the productFlavors command (otherwise moving the flavor source set root fails).
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// We move the root of our flavors to support our legacy structure.
flavor1.setRoot('flavors/flavor1')
flavor2.setRoot('flavors/flavor2')
}
applicationVariants.all { variant ->
def aptOutputDir = project.file("${project.buildDir}/source/apt_generated")
def aptOutput = new File(aptOutputDir, variant.dirName)
println "****************************"
println "variant: ${variant.name}"
println "manifest: ${variant.processResources.manifestFile}"
println "aptOutput: ${aptOutput}"
println "****************************"
android.sourceSets[getSourceSetName(variant)].java.srcDirs+= aptOutput.getPath()
variant.javaCompile.doFirst {
println "*** Running AndroidAnnotations for ${variant.name}"
aptOutput.mkdirs()
variant.javaCompile.options.compilerArgs += [
'-processorpath', configurations.apt.getAsPath(),
'-AandroidManifestFile=' + variant.processResources.manifestFile,
'-s', aptOutput
]
}
variant.javaCompile.source = variant.javaCompile.source.filter { p ->
return !p.getPath().startsWith(aptOutputDir.getPath())
}
}
dependencies {
// Android-Annotations
apt 'com.googlecode.androidannotations:androidannotations:2.7.1'
compile 'com.googlecode.androidannotations:androidannotations-api:2.7.1'
// Include libraries only in flavor1
flavor1Compile fileTree(dir: 'libs', include: '*.jar')
}
Qui è la mia (iniziale) build.gradle
(ho messo a nudo di parti non rilevanti):
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
configurations {
// This is the annotations processor dependency configuration.
apt
}
def getSourceSetName(variant) {
return new File(variant.dirName).getName();
}
android {
compileSdkVersion 18
defaultConfig {
versionCode 10
versionName "1.0.2"
targetSdkVersion 17
minSdkVersion 10
}
buildToolsVersion "18.0.1"
buildTypes {
release {
zipAlign true
}
}
productFlavors {
flavor1 {}
}
// This has to go after the productFlavors command (otherwise moving the flavor source set root fails).
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// We move the root of our flavor to support our legacy structure.
flavor1.setRoot('flavors/flavor1')
}
applicationVariants.all { variant ->
aptOutput = file("${project.buildDir}/source/apt_generated/${variant.dirName}")
println "****************************"
println "variant: ${variant.name}"
println "manifest: ${variant.processResources.manifestFile}"
println "aptOutput: ${aptOutput}"
println "****************************"
// Automatically add the generated source code to the source set
android.sourceSets[getSourceSetName(variant)].java.srcDirs += aptOutput
variant.javaCompile.doFirst {
println "*** Running AndroidAnnotations for ${variant.name}"
aptOutput.mkdirs()
variant.javaCompile.options.compilerArgs += [
'-processorpath', configurations.apt.getAsPath(),
'-AandroidManifestFile=' + variant.processResources.manifestFile,
'-s', aptOutput
]
}
}
}
dependencies {
// Android-Annotations
apt 'com.googlecode.androidannotations:androidannotations:2.7.1'
compile 'com.googlecode.androidannotations:androidannotations-api:2.7.1'
// Include libraries only in flavor1
flavor1Compile fileTree(dir: 'libs', include: '*.jar')
}
Gradirei qualsiasi aiuto.
Grazie, David
Esattamente quello che è successo nella mia situazione. A proposito, i file generati che dovresti rimuovere sono in app/src/main/java/your/package/name. –