Apk 重新打包压缩方案

本文介绍了如何使用Java编程语言,通过ZipOutputStream对目录中的文件进行压缩,并对resources.arsc文件特别处理,计算CRC32校验码,以创建一个新的APK文件。
import java.io.*
import java.util.zip.CRC32
import java.util.zip.CheckedInputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

/**
 * @author heganmin
 * @date 2023/2/22
 */
object ZipApk {
    private const val BUFFER_SIZE = 8192

    @JvmStatic
    fun main(vararg args: String) {
        val dir = File("path/to/dir")
        val apkName = "path/to/apk"
        val files = mutableListOf<File>()
        travelFiles(dir, files)
        ZipOutputStream(FileOutputStream(apkName)).use { zos ->
            val buffer = ByteArray(BUFFER_SIZE)

            files.forEach { file ->
                val entry = ZipEntry(file.toRelativeString(dir))
                entry.size = file.length()
                if ("resources.arsc" == file.name) {
                    entry.method = ZipEntry.STORED
                    val crc32 = BufferedInputStream(FileInputStream(file)).use {
                        calculateCRC32(it)
                    }
                    entry.crc = crc32.value
                } else {
                    entry.method = ZipEntry.DEFLATED
                }
                zos.putNextEntry(entry)
                BufferedInputStream(FileInputStream(file)).use { fis ->
                    while (true) {
                        val length = fis.read(buffer)
                        if (length <= 0) break
                        else zos.write(buffer, 0, length)
                    }
                }
                zos.closeEntry()
            }
            zos.flush()
        }
    }

    private fun travelFiles(file: File, saveList: MutableList<File>) {
        if (file.isFile) {
            saveList.add(file)
        } else if (file.isDirectory) {
            val files = file.listFiles { _, name ->
                !name.startsWith('.')
            } ?: return
            files.forEach {
                travelFiles(it, saveList)
            }
        }
    }

    private fun calculateCRC32(input: InputStream): CRC32 {
        val crc32 = CRC32()
        CheckedInputStream(input, crc32).use {
            while (it.read() >= 0) continue
        }
        return crc32
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值