2016-04-28 103 views
2

我有我自己的Gradle插件,我想添加一个任务,它将从main文件夹中为启动器图标添加一个任务,并为每个构建类型/风味文件夹设置输出图标根据用户的扩展配置不同的颜色。使用资源生成任务添加资源时的“重复资源”

我已经添加用于应用变体的任务:

variant.registerResGeneratingTask(tintTask, new File("${project.buildDir}/generated/res/${variant.name}")) 

然后在任务我执行上述操作。在此之前一切正常 - 生成源文件并将文件夹标记为资源文件夹。

问题是,当我尝试创建一个构建和流程击中mergeXXXResources任务(在这种情况下,xxx == debug)。

在这一点上,我得到一个例外,比较main/res中的mipmap-[dpi]-v4/ic_launchergenerated/res/debug中的mipmap-[dpi]-v4/ic_launcher

例如:

Execution failed for task ':app:mergeDebugResources'. 
[mipmap-hdpi-v4/ic_launcher] /{proj_location}/android_example/app/src/main/res/mipmap-hdpi/ic_launcher.png 
[mipmap-hdpi-v4/ic_launcher] /{proj_location}/android_example/app/build/generated/res/debug/mipmap-hdpi/ic_launcher.png: 
Error: Duplicate resources 

我尝试不同的位置对我的输出文件,但我不认为这有什么差别。我期望资源合并能够识别生成的资源并在最终输出中解析它们,但显然我正在做一些可怕的错误。

我试过使用转换API,但也许是因为缺乏文档和我的理解不够我的尝试不是很成功(我找不到类似于我的方式的资源文件在转换操作期间定位java文件)。

我正在寻找一条关于如何解决我目前问题的建议,或者是一个可以执行我最初着手实现的任务的替代方法。

编辑:的请求,我的任务操作代码:

@TaskAction 
def convertLauncherIcons() { 
    def android = project.extensions.getByType(AppExtension) 
    File outputDir = new File("${project.buildDir}/generated/tintLaunchIcons/res/${taskVariant.name}") 

    android.sourceSets.each { 
     if ("main".equals(it.name)) { 
      it.res.srcDirs.each { dirIt -> 
       dirIt.absoluteFile.list().each { resDir -> 
        if (resDir.startsWith("mipmap-")) { 
         def relIconPath = "${resDir}/ic_launcher.png" 
         File launcherFile = new File(dirIt.absolutePath, relIconPath); 
         if (launcherFile.exists()) { 
          BufferedImage img = ImageIO.read(launcherFile); 
          /* IMAGE MANIPULATION HERE */ 
          File outputFile = new File(outputDir, relIconPath); 
          if (!outputFile.exists()) { 
           File parent = outputFile.getParentFile(); 
           if (!parent.exists() && !parent.mkdirs()) { 
            throw new IllegalStateException("Couldn't create dir: " + parent); 
           } 
           outputFile.createNewFile(); 
          } 
          println "writing file ${outputFile.canonicalPath}" 
          ImageIO.write(img, "png", outputFile); 
     } ... 
+0

您的生成资源的输出路径是什么? – Kelevandos

+0

@Kelevandos是否指项目的合并资源输出?这是标准的,所以'app/build/intermediates/incremental/mergeDebugResources', 'app/build/intermediates/res/merged/debug'和 'app/build/intermediates/blame/res/debug'。但是,只有在注册为resGeneratingTask的任务之后才会执行此操作。 – zilinx

+0

我认为这里的问题是你在构建目录中的任务。尝试将'variant.registerResGeneratingTask'的输出路径设置为主目录,并让Gradle负责将其合并到构建中。让我知道它是否有帮助:) – Kelevandos

回答

2

好了,总结了我们想出了上述评论的讨论:


这里的问题是最有可能的事实是,您正试图在gradle脚本将main目录与当前风格合并之前修改这些文件。我的建议是你应该尝试发射你的任务合并完成后,像这样:

variant.mergeResources.doLast { //fire your task here } 

这应该是一个有点简单,将大量的研究为您节省到了Android gradle这个插件实际上是如何处理这些东西:-)

+0

虽然这是正确的,但它会打破增量构建,因为mergeResources的输出会随着每个构建而变化,所以即使没有对任何源文件进行任何更改,也会触发每个构建的mergeResources – Auras