使用gradle构建将IntelliJ IDEA项目迁移到Android Studio时遇到问题。我已经设置了AndroidAnnotations库,就像其他各种帖子中推荐的一样,它工作得很好。但是,当多次编译我的项目而不执行其中的:clean
任务时,我收到以下错误消息:
/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添加必要性检查吗?或者这是另一个问题吗?
更新1:似乎AndroidAnnotations本身引发了错误,因为:compile
在我手动删除*.java
文件夹中的apt_generated
文件时有效
更新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文件添加到类路径中?
尽管如此,我还是会感激不尽。
更新3 /解决方案
删除行并将gradle构建文件与Android Studio同步后,自动生成的源代码被删除为Source Root,导致IDE显示缺少类的错误。
最终,我在Android Annotations github问题上找到了解决方案:https://github.com/excilys/androidannotations/issues/676
我重新添加了将其添加到源集的语句(允许Android Studio将其显示为源根)。此外,我使用以下方法从变体源集合中删除了文件:
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 :(得分:1)
如果从Eclipse导出build.gradle,它在gradle文件中包含.apt_generated,它不应该。拿出来,这些错误应该消失。
答案 1 :(得分:0)
最终,我在Android Annotations github问题上找到了解决方案:https://github.com/excilys/androidannotations/issues/676
我重新添加了将其添加到源集的语句(允许Android Studio将其显示为源根)。此外,我使用以下方法从变体源集合中删除了文件:
variant.javaCompile.source = variant.javaCompile.source.filter { p ->
return !p.getPath().startsWith(aptOutputDir.getPath())
}
现在识别生成的文件,并且重复的类错误消失了。
最好的问候,大卫