Android 在构建apk时,如何减少xml资产的大小

Android 在构建apk时,如何减少xml资产的大小,android,gradle,build,Android,Gradle,Build,在我的应用程序中,我使用assets目录存储一些XML文件(有些文件很大)。 在我的设计阶段,我希望文件使用缩进,并在其中添加一些注释。 这是在扩大我的xml文件,可以增加到一个很大的大小 在将xml文件打包到apk中之前,是否可以向gradle构建添加一个任务来删除xml文件的所有缩进和注释?如果是,怎么做 这不仅会缩小我的apk,还会在运行时帮助xml处理 编辑 fhomovc的回答是正确的,但遗漏了部分内容。 我会将其标记为正确,但如果其他人需要,请参阅以下详细信息: 通常,我需要一个运行

在我的应用程序中,我使用assets目录存储一些XML文件(有些文件很大)。 在我的设计阶段,我希望文件使用缩进,并在其中添加一些注释。 这是在扩大我的xml文件,可以增加到一个很大的大小

在将xml文件打包到apk中之前,是否可以向gradle构建添加一个任务来删除xml文件的所有缩进和注释?如果是,怎么做

这不仅会缩小我的apk,还会在运行时帮助xml处理

编辑

fhomovc的回答是正确的,但遗漏了部分内容。 我会将其标记为正确,但如果其他人需要,请参阅以下详细信息:

通常,我需要一个运行minify实用程序的任务,它应该如下所示:

task minifyAssets(type:Exec) {
    workingDir dirName // the directory of the merged assets under the build directory
    commandLine 'minify', '-r', '-o', '.', '.'
    doFirst {
        println 'minifyAssets...'
    }
}
仅应在执行合并资产任务之后和执行包任务之前执行此任务

主要问题是每个变量都应该有一个专用任务,所以我需要动态地执行它:

首先创建exec任务并使其依赖于合并任务

    applicationVariants.all { variant ->
        // dynamically add minify task for specific variant
        def dirName = new File("app\\build\\intermediates\\merged_assets\\"  + variant.name + "\\out\\levels").getAbsolutePath()
        def minifyTaskName = "minifyAssets" + variant.name
        def mergeAssetsTaskName = "merge" + variant.name + "Assets"
        def myTask = tasks.register(minifyTaskName, Exec) {
            workingDir dirName
            // require that minify utility will be in the path. Download from https://github.com/tdewolff/minify/tree/master/cmd/minify
            commandLine 'minify', '-r', '-o', '.', '.'
            doFirst {
                println 'minifyAssets...' + workingDir
            }
        }
        // set the minify task dependant on the merge assets task
        myTask.get().dependsOn mergeAssetsTaskName
    }
现在我们需要使特定的包任务取决于缩小任务:

// when the package task is added make it dependant on the minify task
tasks.whenTaskAdded { theTask ->
    if (theTask.name.startsWith("package") && (theTask.name.endsWith("Debug") || theTask.name.endsWith("Release"))) {
        def minifyTaskName = theTask.name.replace("package", "minifyAssets")
        theTask.dependsOn minifyTaskName
    }
}

可以使用xml缩略器运行自定义脚本

  • 对于minifier:您可以按照提供的安装步骤进行安装
  • 对于脚本:您可以参考。基本上,您的任务看起来是这样的

    task executeScript(type:Exec) {
        println 'Minifying xmls...'
        //on linux
        commandLine 'minify -r -o ./ --match=\.xml ./values' // ./values should be the path to your resources directory
    }
    

查看文档以更好地了解minify的工作原理。我自己还没有测试过这个解决方案,所以它可能需要一些调整,但您已经了解了总体思路。如果您使用的是Windows计算机,那么脚本(
命令行
)应该不同,如果我可以在线找到任何示例,我将添加它们。

您可以使用xml缩略器运行自定义脚本

  • 对于minifier:您可以按照提供的安装步骤进行安装
  • 对于脚本:您可以参考。基本上,您的任务看起来是这样的

    task executeScript(type:Exec) {
        println 'Minifying xmls...'
        //on linux
        commandLine 'minify -r -o ./ --match=\.xml ./values' // ./values should be the path to your resources directory
    }
    

查看文档以更好地了解minify的工作原理。我自己还没有测试过这个解决方案,所以它可能需要一些调整,但您已经了解了总体思路。如果您使用的是Windows计算机,那么脚本(
命令行
)应该不同,如果我可以在线找到任何示例,我将添加它们。

您尝试过压缩资源吗?否则,您可以只运行一个带有xml minifyer的脚本,就像这样谢谢您的回复。据我所知,资源的缩减是关于删除未使用的资源,因此这与此无关。关于minify,它可能是一个解决方案,但我不知道如何将它集成到build.gradle中。你能帮忙吗?你试过缩减资源吗?否则,您可以只运行一个带有xml minifyer的脚本,就像这样谢谢您的回复。据我所知,资源的缩减是关于删除未使用的资源,因此这与此无关。关于minify,它可能是一个解决方案,但我不知道如何将它集成到build.gradle中。你能帮个忙吗?这看起来像是我正在寻找的选择,但是有一些问题:1。我不想更改原始文件。从我看到的情况来看,构建系统将资产目录复制到app\build\mediates\merged\u assets\???(每个风格的目录),我想更改那里的文件。2.执行任务时,构建将资产复制到该目录之前。3.如何获取对该目录的引用(我不想使用硬编码目录)。4.当尝试运行一个不存在的脚本时,它没有使构建失败(如果发生错误,我需要停止构建)1) 您可以使用
-o
选项来使用不同的输出文件夹:
缩小-o./merged\u assets//values
或者您可以在
executeScript
中使用
workingDir'app\build\intermediates\merged\u assets\'
。2) 检查我链接的答案中的
gradle.projectsEvaluated{assembleerelease.dependsOn executeScript}
选项。3) 您可以在gradle.properties中添加参数并在运行时加载它。您还可以从控制台运行它并在那里添加参数。4) 检查此问题stackoverflow.com/questions/34234820和
execResult
value。祝你好运如果我使用的是您描述的executeScript,它将在配置阶段运行它(这不是我需要的)。我试图更改它并将代码放入doLast块中,但收到错误:任务执行失败“:app:minifyAssets”。>execCommand==null!我认为这是正确的,因为这是一种方式,但它并不完整。我用完整的答案更新了这个问题。谢谢你的帮助。这看起来像是我正在寻找的选项,但是有一些问题:1。我不想更改原始文件。从我看到的情况来看,构建系统将资产目录复制到app\build\mediates\merged\u assets\???(每个风格的目录),我想更改那里的文件。2.执行任务时,构建将资产复制到该目录之前。3.如何获取对该目录的引用(我不想使用硬编码目录)。4.当尝试运行一个不存在的脚本时,它没有使构建失败(如果发生错误,我需要停止构建)1) 您可以使用
-o
选项来使用不同的输出文件夹:
缩小-o./merged\u assets//values
或者您可以在
executeScript
中使用
workingDir'app\build\intermediates\merged\u assets\'
。2) 检查我链接的答案中的
gradle.projectsEvaluated{assembleerelease.dependsOn executeScript}
选项。3) 您可以在gradle.properties中添加参数并在运行时加载它。您还可以从控制台运行它并在那里添加参数。4) 检查此问题stackoverflow.com/questions/34234820和
execResult
value。祝你好运如果我使用的是你描述的executeScript,