5

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...]

*_.javaAndroidAnnotations は常にタスクの前にファイルを再作成し:compile(必要かどうかを確認せずに)、:compileタスクは新しいファイルを認識しますが (タイムスタンプを使用するなど)、それらをプリコンパイル済み*.classファイルとして既に検出しているため、複数のビルドが連続して失敗すると思います。 、したがってエラーをスローします。これは可能ですか?この動作を防ぐにはどうすればよいですか? AndroidAnnotations の必要性チェックを追加できますか? それとも、これは別の問題ですか?


更新 1: AndroidAnnotations 自体からエラーがスローされたようです。これは、フォルダー内のファイルを手動で:compile削除すると機能するためです。*.javaapt_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 と同期した後、自動生成されたソース コードがソース ルートとして削除され、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')
}

助けていただければ幸いです。

ありがとう、デビッド

4

2 に答える 2

1

build.gradle を Eclipse からエクスポートすると、gradle ファイルに .apt_generated が含まれますが、含まれるべきではありません。これを取り除くと、これらのエラーはなくなります。

于 2013-12-02T21:54:17.530 に答える