You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在APK构建过程中自动压缩res/raw与assets中的XML、JSON文件?

自动压缩res/raw和assets中的XML/JSON文件

当然可以在构建流程里自动搞定这个压缩需求!AGP、R8这些默认确实不会处理XML、JSON这类文本资源,但咱们可以通过自定义Gradle任务或者借助工具库把这个流程自动化,完全不用手动折腾啦。

我给你两种实用方案,你可以根据自己的需求选:


方案一:纯Gradle自定义任务(无额外依赖)

这个方案会在构建的资源处理阶段,自动遍历res/rawassets下的XML、JSON文件,移除注释、冗余空白这类无用内容,同时保证文件格式合法。

步骤1:在app模块的build.gradle里加任务配置

把这段代码贴到你的build.gradle(Groovy语法)里:

// 压缩JSON文件的任务
task minifyJsonFiles(type: Copy) {
    // 匹配assets和res/raw下所有.json文件
    from 'src/main/assets', 'src/main/res/raw'
    include '**/*.json'
    
    // 输出到临时目录,不修改源文件
    def tempDir = file("$buildDir/tmp/minifiedJson")
    into tempDir
    
    // 处理每个JSON:移除注释和冗余空白
    eachFile { file ->
        filter { line ->
            // 去掉单行注释
            !line.trim().startsWith('//') && 
            // 去掉多行注释的首尾标记
            !line.trim().startsWith('/*') && !line.trim().endsWith('*/')
        }
        // 移除多余空白字符(保留必要结构)
        filter { it.replaceAll(/\s+/, ' ') }
    }
}

// 压缩XML文件的任务
task minifyXmlFiles(type: Copy) {
    from 'src/main/assets', 'src/main/res/raw'
    include '**/*.xml'
    
    def tempDir = file("$buildDir/tmp/minifiedXml")
    into tempDir
    
    // 移除XML注释和标签间的空白
    eachFile { file ->
        filter(StripXmlComments)
        filter { it.replaceAll(/>\s+</, '><') }
    }
}

// 自定义过滤器:移除XML注释
class StripXmlComments extends FilterReader {
    StripXmlComments(Reader in) { super(in) }
    String readLine() {
        String line = super.readLine()
        while (line != null) {
            def stripped = line.replaceAll(/<!--.*?-->/, '').trim()
            if (!stripped.isEmpty()) {
                return stripped
            }
            line = super.readLine()
        }
        return null
    }
}

// 让压缩任务在构建前执行
preBuild.dependsOn minifyJsonFiles, minifyXmlFiles

// 让资源合并任务使用压缩后的文件
android.sourceSets.main.res.srcDirs += minifyXmlFiles.outputs.files.asFileTree
android.sourceSets.main.assets.srcDirs += minifyJsonFiles.outputs.files.asFileTree

步骤2:保留你的原有release配置

你现在的release配置已经开了混淆和资源收缩,和这个压缩任务完全不冲突,继续用就行:

release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    shrinkResources true
}

方案二:用专业工具库压缩(更可靠彻底)

如果需要更专业的压缩(比如JSON语法优化、XML冗余节点清理),可以用专门的工具库,比如Jackson处理JSON,XmlUnit处理XML。这里以Jackson为例:

步骤1:添加依赖到build.gradle

buildscript {
    dependencies {
        classpath 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
    }
}

步骤2:修改JSON压缩任务

import com.fasterxml.jackson.databind.ObjectMapper

task minifyJsonFiles(type: Copy) {
    from 'src/main/assets', 'src/main/res/raw'
    include '**/*.json'
    
    def tempDir = file("$buildDir/tmp/minifiedJson")
    into tempDir
    
    eachFile { file ->
        filter { content ->
            ObjectMapper mapper = new ObjectMapper()
            // 读取JSON并输出为最小化格式,保证语法绝对正确
            mapper.writeValueAsString(mapper.readTree(content))
        }
    }
}

这种方式比正则替换更可靠,能确保压缩后的JSON完全符合语法规范,不会出现解析问题。


验证效果

配置好后,执行./gradlew assembleRelease,然后用APK Analyzer打开生成的APK,看看res/rawassets下的文件体积,应该和你手动压缩后的效果一致。

⚠️ 注意事项:

  • 如果有些文件需要保留注释或格式(比如应用要读取注释的配置文件),可以修改include规则,用exclude把这些文件排除在外。
  • 先跑./gradlew assembleDebug测试一下,确保压缩后的文件能被应用正常读取,避免格式错误导致崩溃。

内容的提问来源于stack exchange,提问作者Maksim Turaev

火山引擎 最新活动