5

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 *.javaapt_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

risposta

0

Alla fine, ho trovato la soluzione sulle questioni GitHub Annotazioni Android: https://github.com/excilys/androidannotations/issues/676

ho ri-aggiunge il comunicato per aggiungerlo ai set di origine (che permette Android Studio per vederlo come root di origine). 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

1

Se si esporta il build.gradle da Eclipse, include .apt_generated nel file Gradle e non dovrebbe. Toglilo e questi errori dovrebbero andare via.

+0

Esattamente quello che è successo nella mia situazione. A proposito, i file generati che dovresti rimuovere sono in app/src/main/java/your/package/name. –

Problemi correlati