5

У меня возникла проблема с переносом моего проекта IntelliJ IDEA на Android Studio с использованием сборки градации. Я установил библиотеку AndroidAnnotations, как рекомендуется в других других сообщениях, и она работает нормально. Но при компиляции моего проекта несколько раз без выполнения :clean задачи между ними, я получаю следующее сообщение об ошибке:Gradle + AndroidAnnotations генерирует повторяющиеся ошибки класса - нужно очистить проект перед каждой сборкой

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

[more errors here...] 

Я считаю, что несколько вариантов сборки в серии не потому, что AndroidAnnotations повторно создает *_.java файлы всегда перед :compile задач (без проверки необходимости или нет), а задача :compile распознает новые файлы (например, используя временную метку), но уже находит их как предварительно скомпилированные файлы *.class, тем самым вызывая ошибку. Это возможно? Как я могу предотвратить это поведение? Могу ли я добавить проверку необходимости для AndroidAnnotations? Или это еще одна проблема?


UPDATE 1: кажется, что ошибка возникает из самой AndroidAnnotations, так :compile работ, когда я удалить *.java файлы внутри папки apt_generated вручную.


UPDATE 2:

я удалил следующую строку из моих build.gradle:

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

Я точно не знаю, почему она работает без этой линии. Поскольку я не добавлял папку с помощью Android Studio Mark Directory as > Sources Root. Возможно, это результат кэширования? Или же gradle каким-то образом автоматически добавляет созданные java-файлы в classpath?

Я был бы благодарен за любые комментарии, тем не менее.


UPDATE 3/РЕШЕНИЕ

После удаления строки и синхронизации Gradle файл сборки с Android Studio, сгенерированный автоматически исходный код был удален как Source Root, в результате чего IDE, чтобы показать ошибки отсутствующие классы.

В конце концов, я нашел решение по вопросам Android Аннотации GitHub: https://github.com/excilys/androidannotations/issues/676

Я снова добавил заявление для добавления его к наборам исходных (с учетом Android студии, чтобы показать его в качестве корневого источника). Кроме того, я удалил файлы из коллекции вариантов источника с помощью этого:

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

Теперь сгенерированные файлы распознаются, и исчезает ошибка Дубликат класса.

С наилучшими пожеланиями, Дэвид

Вот мой окончательный build.gradle.Я надеюсь, что это помогает некоторым из вас:

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

Вот мой (начальный) build.gradle (я лишен, не являющихся соответствующих частей):

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

Я был бы признателен за любую помощь.

Спасибо, Дэвид

ответ

0

В конце концов, я нашел решение по вопросам GitHub Android Аннотации: https://github.com/excilys/androidannotations/issues/676

Я снова добавил заявление для добавления его к наборам исходных (позволяя Android студии, чтобы показать его как исходный корень). Кроме того, я удалил файлы из коллекции вариантов источника с помощью этого:

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

Теперь сгенерированные файлы распознаются, и исчезает ошибка Дубликат класса.

С наилучшими пожеланиями, Дэвид

1

Если вы экспортируете build.gradle из Eclipse, она включает в себя .apt_generated в Gradle файл и он не должен. Возьмите это, и эти ошибки должны исчезнуть.

+0

То, что произошло в моей ситуации. Кстати, сгенерированные файлы, которые вы должны удалить, находятся в файле app/src/main/java/your/package/name. –

 Смежные вопросы

  • Нет связанных вопросов^_^