Gradle + 注解 + 渠道包 = 注解处理器无法运行

14

我有一个使用注解处理器(Android Annotations)生成代码的Gradle构建脚本。在添加了一个新的Pro Flavor之后,构建过程出现问题。我可以成功构建Free flavor,但当我构建Pro flavor时,注解处理器不会运行。这导致缺失代码和构建失败。

以下是我的脚本:

buildscript {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}
apply plugin: 'android'

repositories {
    mavenCentral()
    maven {
        url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
}


ext.androidAnnotationsVersion = '3.0-SNAPSHOT';

configurations {
    apt
}


dependencies {
    compile files('libs/android-support-v13.jar')
    compile fileTree(dir: 'libs', include: '*.jar')
    apt "org.androidannotations:androidannotations:${androidAnnotationsVersion}"
    compile "org.androidannotations:androidannotations-api:${androidAnnotationsVersion}"
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"


    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 17

        versionCode 29
        versionName "2.0.3"
        packageName "com.MyCompany.MyApp"

    }

    productFlavors {
        free {
            buildConfig "final public static boolean PRO_VERSION = false;"
        }
        pro {
            packageName "com.MyCompany.MyApp.Pro"
            versionName (versionName + ".Pro")
            buildConfig "final public static boolean PRO_VERSION = true;"
        }
    }

    buildTypes {
        release {
            buildConfig "final public static String BASE_URL = \"http://data.MyCompany.com/\";", \
                        "final public static String APP_NAME = \"com.MyCompany.MyApp\";"
        }
        debug {
            buildConfig "final public static String BASE_URL = \"http://192.168.1.15/GDM/\";", \
                        "final public static String APP_NAME = \"com.MyCompany.MyApp\";"
        }
    }

}

def getSourceSetName(variant) {
    return new File(variant.dirName).getName();
}

android.applicationVariants.all { variant ->
    def aptOutputDir = project.file("build/source/apt")
    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.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())
    }

    variant.javaCompile.doFirst {
        aptOutput.mkdirs()
    }
}

构建免费版本时,如下所示在gradle输出中运行注解处理器:

Note: Starting AndroidAnnotations annotation processing

构建Pro版本时,注解处理器不会运行,因此对生成代码的引用将失败。

有趣的是,我(真正偶然地)发现,如果我从脚本中删除packageName "com.MyCompany.MyApp.Pro",则注释处理器将运行并且可以正确构建。但我需要更新软件包名称以适应Google Play。

在Android Studio中查看时,可以看到apt(注释处理工具)显示Pro版本正在运行,即使我选择了FreeDebug构建变体。我不确定这是否表示问题或者这只是测试版Android Studio(Android Studio版本:0.2.13)的问题。所以这要带着一定程度的怀疑看待。

Android Studio中的Build Folders

我对Gradle构建系统还很陌生,但我认为我已经开始理解了。我一遍又一遍地查看了脚本,但我不知道为什么注解处理器不能运行pro变体。除了使用--info和--debug参数运行wrapper之外,我还不知道如何调试这些问题。

我运行了带-info-debug标志的gradle wrapper,以获取扩展输出,但直到它达到由于缺少生成的代码而引起的错误之前,没有任何指示其他错误(或缺失项)。因此,这使我相信根本问题是该变体未运行androidannotations。(即,我认为这不是由上游错误引起并在以后被错误报告的错误。当然,我也可能是错的)

我真的很困惑,已经卡在这里两天了。

1个回答

13

我成功解决了这个问题。在仔细查看Gradle包装器的-info输出后,我发现androidAnnotations试图运行。错误输出的顺序不正确,因为注解处理消息出现在由引用不存在的代码(因为注解处理失败而不存在)引起的错误之后。

以下是日志:

:MyCompany:compileProDebug
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:14: error: cannot find symbol
import com.MyCompany.MyApp.Notifications.NotificationSetupActivity_;
                                                ^
  symbol:   class NotificationSetupActivity_
  location: package com.MyCompany.MyApp.Notifications
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:24: error: cannot find symbol
import com.MyCompany.MyApp.FantasyScores.ActivityScores_;
                                                ^
  symbol:   class ActivityScores_
  location: package com.MyCompany.MyApp.Scores
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:32: error: cannot find symbol
import com.MyCompany.MyApp.Team.activityTeamSelect_;
                                       ^
  symbol:   class activityTeamSelect_
  location: package com.MyCompany.MyApp.Team
Note: Starting AndroidAnnotations annotation processing
Note: AndroidManifest.xml file found: ....\build\manifests\pro\debug\AndroidManifest.xml
error: The generated com.MyCompany.MyAppPro.R class cannot be found
Note: Time measurements: [Whole Processing = 190 ms], [Extract Manifest = 129 ms], [Extract Annotations = 49 ms],
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:14: error: cannot find symbol
import com.MyCompany.MyApp.Notifications.NotificationSetupActivity_;
重要的行如下: 注意:开始 AndroidAnnotations 注解处理 注意:找到了 AndroidManifest.xml 文件:....\build\manifests\pro\debug\AndroidManifest.xml 错误:找不到生成的 com.MyCompany.MyAppPro.R 类 这些应该首先出现在错误日志中,因为注解处理器在完整编译步骤之前运行,但由于某种原因它们被深深埋没了(也许是 androidannotations 处理器的刷新问题??)
无论如何,第三行找不到 com.MyCompany.MyAppPro.R 是关键。资源实际上位于 com.MyCompany.MyApp.R(没有 Pro)。经过一番挖掘,我发现这篇文章表明这是 AndroidAnnotations 已知的问题。
我通过向构建脚本添加'-AresourcePackageName=MyBasePackageName' 参数解决了这个问题。注意:这仅适用于使用 3.0 快照版本的情况。最新发布的 AndroidAnnotations 版本不支持 -AresourcePackageName 选项。
添加参数后,所有变体都能够正确构建。构建脚本的 compilerArgs 部分现在看起来像这样:
variant.javaCompile.options.compilerArgs += [
        '-processorpath', configurations.apt.getAsPath(),
        '-AandroidManifestFile=' + variant.processResources.manifestFile,
        '-AresourcePackageName=MyBasePackageName',
        '-s', aptOutput
]

希望这能帮助其他人避免未来出现此问题。


感谢您分享解决方案。 - ruX
太好了!谢谢你!有没有办法以编程方式提取基本包名称? - Jacob Tabak
回到十月份时,我简单地尝试过能否做到这一点。这不是完全明显的事情,由于时间紧迫,我没有深入追究它。理论上应该可以将其拉入,但我不知道如何立即做到。 - Michael Stoner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接