5

Ich habe ein Problem mit der Migration meines IntelliJ IDEA-Projekts auf Android Studio mithilfe eines Gradle-Builds. Ich habe die AndroidAnnotations-Bibliothek wie in anderen Posts empfohlen eingerichtet, und es funktioniert gut. Aber wenn mein Projekt mehrmals kompilieren, ohne die Ausführung der :clean Aufgabe dazwischen, erhalte ich folgende Fehlermeldungen:Gradle + AndroidAnnotations erzeugt doppelte Klassenfehler - muss vor jedem Build ein Projekt bereinigen

/project-dir/build/source/apt_generated/flavor1/release/com/example/app/MyActivity_.java:15: error: duplicate class: com.example.app.MyActivity_ 

[more errors here...] 

Ich glaube, dass mehrere baut in Serie scheitern, weil AndroidAnnotations neu erstellt die *_.java Dateien immer vor den :compile Aufgaben (ohne zu prüfen, ob es notwendig ist oder nicht) und die :compile Aufgabe erkennt die neuen Dateien (zB mit Timestamp) aber findet diese bereits als vorkompilierte *.class Dateien, die den Fehler auslösen. Ist das möglich? Wie kann ich dieses Verhalten verhindern? Kann ich eine Notwendigkeitsprüfung für AndroidAnnotations hinzufügen? Oder ist das ein anderes Problem?


UPDATE 1: Es scheint, dass der Fehler von AndroidAnnotations geworfen wird sich, da :compile funktioniert, wenn ich die *.java Dateien im apt_generated Ordner manuell löschen.


UPDATE 2:

ich folgende Zeile aus meinem build.gradle entfernt:

// Automatically add the generated source code to the source set 
android.sourceSets[getSourceSetName(variant)].java.srcDirs += aptOutput 

Ich weiß nicht genau, warum es ohne diese Linie funktioniert. Da ich den Ordner nicht mit Android Studio Mark Directory as > Sources Root hinzugefügt habe. Wahrscheinlich ist das ein Ergebnis des Caching? Oder fügt Gradle irgendwie meine generierten Java-Dateien automatisch dem Klassenpfad hinzu?

Ich wäre trotzdem dankbar für Kommentare.


UPDATE 3/SOLUTION

nach der Zeile zu entfernen und die gradle Build-Datei mit Android Studio, die automatisch generierte Quellcode wurde als Source Root Synchronisierung entfernt, wodurch die IDE verursachten Fehler zu zeigen, fehlende Klassen

Schließlich fand ich die Lösung auf den Android Anmerkungen Github Fragen: https://github.com/excilys/androidannotations/issues/676

ich die Aussage erneut hinzugefügt, um es mit den Source-Sets hinzugefügt (so dass Android Studio als Quelle Wurzel zeigen). Darüber hinaus nahm ich die Dateien aus der Variante Quellensammlung dies mit:

variant.javaCompile.source = variant.javaCompile.source.filter { p -> 
    return !p.getPath().startsWith(aptOutputDir.getPath()) 
} 

Nun wird die erzeugten Dateien erkannt werden, und der doppelte Klassenfehler verschwunden ist.

Mit freundlichen Grüßen, David

Hier ist meine letzte build.gradle.Ich hoffe, das einige von Ihnen hilft:

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') 
} 

Hier ist meine (initial) build.gradle (I von nicht relevanten Teile gestrippt):

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') 
} 

Ich würde jede Hilfe dankbar.

Danke, David

Antwort

0

Schließlich fand ich die Lösung auf den Github Fragen Android Anmerkungen: https://github.com/excilys/androidannotations/issues/676

ich die Aussage erneut hinzugefügt, um es mit den Source-Sets für das Hinzufügen (so dass Android Studio zeigen als Quellwurzel). Darüber hinaus nahm ich die Dateien aus der Variante Quellensammlung dies mit:

variant.javaCompile.source = variant.javaCompile.source.filter { p -> 
    return !p.getPath().startsWith(aptOutputDir.getPath()) 
} 

Nun wird die erzeugten Dateien erkannt werden, und der doppelte Klassenfehler verschwunden ist.

Mit freundlichen Grüßen, David

1

Wenn Sie die build.gradle von Eclipse-exportieren, enthält es in der gradle Datei .apt_generated und sollte es nicht. Nimm das heraus und diese Fehler sollten verschwinden.

+0

Genau was in meiner Situation passiert ist. Die generierten Dateien, die Sie entfernen sollten, befinden sich übrigens in app/src/main/java/your/package/name. –