首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gradle + AndroidAnnotations生成重复的类错误--需要在每次构建之前清理项目

Gradle + AndroidAnnotations生成重复的类错误--需要在每次构建之前清理项目
EN

Stack Overflow用户
提问于 2013-09-23 11:44:39
回答 2查看 3K关注 0票数 5

在使用gradle构建将我的IntelliJ IDEA项目迁移到Android时,我遇到了问题。我已经设置了AndroidAnnotations库,就像在其他各种帖子中推荐的那样,而且它工作得很好。但是,在不执行:clean任务的情况下多次编译我的项目时,我会得到以下错误消息:

代码语言:javascript
复制
/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总是在:compile任务之前重新创建:compile文件(而不检查是否必要)和:compile任务识别新文件(例如使用时间戳),但是已经发现这些文件是预编译的*.class文件,从而引发错误。这个是可能的吗?我怎样才能防止这种行为?我可以添加一个必需品-检查AndroidAnnotations吗?还是其他的问题?

更新1:似乎是从AndroidAnnotations本身抛出错误的,因为当我手动删除apt_generated文件夹中的*.java文件时,:compile可以工作。

更新2:

我从我的build.gradle中删除了下面一行

代码语言:javascript
复制
// Automatically add the generated source code to the source set
android.sourceSets[getSourceSetName(variant)].java.srcDirs += aptOutput

我不知道为什么没有这句话。因为我没有使用Android的Mark Directory as > Sources Root添加文件夹。这可能是缓存的结果吗?或者gradle是否以某种方式将生成的java文件自动添加到类路径中?

尽管如此,我还是要感谢各位的评论。

更新3/解决方案

删除行并将gradle构建文件与Android同步后,自动生成的源代码被删除为source,从而导致IDE显示缺少类的错误。

最后,我在Android注释github问题上找到了解决方案:https://github.com/excilys/androidannotations/issues/676

我重新添加了将其添加到源集的语句(允许Android将其显示为源根)。此外,我使用以下方法从变体源代码集合中删除了这些文件:

代码语言:javascript
复制
variant.javaCompile.source = variant.javaCompile.source.filter { p ->
    return !p.getPath().startsWith(aptOutputDir.getPath())
}

现在,生成的文件被识别,重复的类错误消失了。

向你问好,大卫

这是我的最后一个build.gradle。我希望这能帮到你们中的一些人:

代码语言:javascript
复制
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 (我去掉了非相关部分):

代码语言:javascript
复制
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')
}

我很感谢你的帮助。

谢谢你,大卫

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-03 09:35:18

最后,我在Android注释github问题上找到了解决方案:https://github.com/excilys/androidannotations/issues/676

我重新添加了将其添加到源集的语句(允许Android将其显示为源根)。此外,我使用以下方法从变体源代码集合中删除了这些文件:

代码语言:javascript
复制
variant.javaCompile.source = variant.javaCompile.source.filter { p ->
    return !p.getPath().startsWith(aptOutputDir.getPath())
}

现在,生成的文件被识别,重复的类错误消失了。

向你问好,大卫

票数 0
EN

Stack Overflow用户

发布于 2013-12-02 21:54:17

如果您从Eclipse导出build.gradle,它将.apt_generated包含在gradle文件中,而它不应该。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18958388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档