android gradle build resources.arsc文件未压缩问题解决
来源:互联网 发布:英雄联盟账号淘宝 编辑:程序博客网 时间:2024/06/11 06:32
随着google如火如荼的推出android studio IDE和gradle buld工具,很多公司要对build系统做从ant到gradle的升级,不幸的是我被分配负责该任务。
发现一个问题,gralde编译后的apk比ant要大大约1M左右,对于老大之前严格要求控制apk在10M左右的需求,只能说造化弄人。压缩包打开发现gradle build之后的apk resources.arsc没有压缩,导致apk增大很多。
于是乎,设置resource shrink 为true,结果如下:
图一:ant打包之后的详单:
图二:gradle shrinkResources false的详单
图三:gradle shrinkResources true的详单
结果发现:ant打包后的resources.arsc,从1.1M压缩到267K,还是比较狠的。
至于是否shrinkResources,没有什么效果
aapt l -v Client-release-unsigned-ant.apk ,查看apk明细:
发现ant包和gradle包的差异:Length Method Size Ratio Offset Date Time CRC-32 Name1158688 Deflate 273481 76% 9835381 11-17-15 15:18 04aecb3e resources.arsc -------- <span style="color:#ff0000;">ant build apk</span>1158508 Stored 1158508 0% 2899860 11-17-15 15:21 9222ccf9 resources.arsc -------- <span style="color:#ff0000;">gradle build apk</span>
ant build resources.arsc是deflate method,而gradle build 的是stored method,而且size相差很大。
于是乎,寻找gradle设置deflate模式的配置开关,未果,似乎是硬编码方式,不支持dsl配置,只能从最后的apk包下手,对resources做二次压缩。下面代码:
apply plugin: 'android'dependencies { compile fileTree(dir: 'libs', include: '*.jar') compile project(':MyProj')}android { compileSdkVersion 19 buildToolsVersion '21.1.2' lintOptions { abortOnError false } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } // Move the tests to tests/java, tests/res, etc... instrumentTest.setRoot('tests') // Move the build types to build-types/<type> // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... // This moves them out of them default location under src/<type>/... which would // conflict with src/ being used by the main source set. // Adding new build types or product flavors should be accompanied // by a similar customization. debug.setRoot('build-types/debug') release.setRoot('build-types/release') } defaultConfig { multiDexEnabled true } dexOptions { javaMaxHeapSize "2g" jumboMode true } buildTypes { debug { minifyEnabled false proguardFile('proguard.cfg') } release { minifyEnabled true proguardFile('proguard.cfg') } } packagingOptions { exclude('META-INF/DEPENDENCIES') exclude('META-INF/NOTICE') exclude('META-INF/LICENSE') } lintOptions { // Or, if you prefer, you can continue to check for errors in release builds, checkReleaseBuilds false // but continue the build even when errors are found: abortOnError false }}import java.util.zip.ZipEntryimport java.util.zip.ZipFileimport java.util.zip.ZipOutputStream// 打包过程中很多手工zip过程:// 1,为了压缩resources.arsc文件而对标准产出包重新压缩// 2,以及各子apk的纯手打apk包// 但对于音频等文件,压缩会导致资源加载报异常// 重新打包方法,使用STORED过滤掉不应该压缩的文件们// 后缀名列表来自于android源码def repackApk(originApk, targetApk){ def noCompressExt = [".jpg", ".jpeg", ".png", ".gif", ".wav", ".mp2", ".mp3", ".ogg", ".aac", ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", ".amr", ".awb", ".wma", ".wmv"] ZipFile zipFile = new ZipFile(originApk) ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(targetApk))) zipFile.entries().each{ entryIn -> if(entryIn.directory){ println "${entryIn.name} is a directory" } else{ def entryOut = new ZipEntry(entryIn.name) def dotPos = entryIn.name.lastIndexOf('.') def ext = (dotPos >= 0) ? entryIn.name.substring(dotPos) : "" def isRes = entryIn.name.startsWith('res/') if(isRes && ext in noCompressExt){ entryOut.method = ZipEntry.STORED entryOut.size = entryIn.size entryOut.compressedSize = entryIn.size entryOut.crc = entryIn.crc } else{ entryOut.method = ZipEntry.DEFLATED } zos.putNextEntry(entryOut) zos << zipFile.getInputStream(entryIn) zos.closeEntry() } } zos.finish() zos.close() zipFile.close()}task repack(){doLast{print "root dir is : $rootDir"println "release打包之后,重新压缩一遍,以压缩resources.arsc"def oldApkFile = file("$rootDir/projectPath/build/outputs/apk/Client-release-unsigned.apk")assert oldApkFile != null : "没有找到release包!"def newApkFile = new File("$rootDir/projectPath/build/outputs/apk/Client-release-unsigned-repack.apk")print oldApkFile.absolutePathprint newApkFile.absolutePath//重新打包repackApk(oldApkFile.absolutePath, newApkFile.absolutePath)assert newApkFile.exists() : "没有找到重新压缩的release包!"}}
其实也可以通过java或者python程序终结对apk进行二次处理达到效果,但是不如gradle处理的自然。
done, perfect !
0 0
- android gradle build resources.arsc文件未压缩问题解决
- Android resources.arsc文件与资源防护
- Android resources.arsc资源文件防护原理分析
- Android resources.arsc资源文件防护原理分析
- Android gradle build时出现Duplicate resources
- Android build.gradle文件
- Android build.gradle文件详解
- Android 详解 build.gradle 文件
- resources.arsc (apk中的资源文件:键值对)
- 记一次resources.arsc文件hex修改原理分析
- resources.arsc 格式
- Android Studio中build.gradle文件详解
- android studio中的build.gradle文件
- 【Android】基础之build.gradle文件
- android studio build.gradle 文件详解
- Android Studio中的build.gradle文件解析
- android中build.gradle文件简单说明
- android studio的build.gradle文件分析
- 正则表达式
- 第十周练习 1001 ASCII码排序
- MySql中允许远程连接
- 常见网络通信概念_TCP UDP
- Android HAL Stub框架分析 .
- android gradle build resources.arsc文件未压缩问题解决
- 关于JSON的一些总结
- 5-5
- 分页查询记录总页数
- Openwrt上配置Aria2迅雷离线下载步骤
- DateUtils.truncate()
- 5-6
- Hibernate如何一个类映射两个表
- 如何写好博客——网文版式设计技巧