"Duplicate resources" 使用资源生成任务添加资源时

"Duplicate resources" when adding resources with a res generating task

我有自己的 Gradle 插件,我想在其中添加一个任务,该任务将从 main 文件夹中获取启动器图标,并为每个构建 type/flavor 文件夹输出带有颜色的图标不同的颜色取决于用户的分机配置。

我已经为应用程序变体添加了任务:

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

然后在任务中我执行上面描述的操作。直到这里一切都很好 - 源已生成并且文件夹被标记为资源文件夹。

问题是当我尝试创建构建时流程遇到了 mergeXXXResources 任务(在本例中为 xxx == debug)。

此时我在比较 main/resgenerated/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

我为我的输出文件尝试了不同的位置,但我认为这没有任何区别。我希望资源合并能够识别生成的资源并在最终输出中解析它们,但显然我做错了一些可怕的事情。

我试过使用 Transform 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);
       } ... 

好的,总结一下我们在上面的评论讨论中得出的结论:


这里的问题很可能是您试图在 gradle 脚本将 main 目录与当前风格合并之前修改文件。我的建议是您应该在合并完成后尝试触发您的任务,如下所示:

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

这应该更简单一些,可以让您省去很多关于 Android gradle 插件如何实际处理这些东西的研究:-)