Android-APK瘦身实践:二次瘦身如何再减少大小?(4M—2-9M)

已经去除不相关的大型库
图片和代码已经经历过粗略的一轮清理

开始魔鬼瘦身

1. tinypng有损压缩

Android打包本身会对png进行无损压缩,不信大家可以看看apk中的图片的大小实际上比你代码工程里的图片要小(针对没进行过无损压缩的那些png图)。

所以,纯粹的进行无损压缩并不会对apk的减小有任何效果,这是我特别想在这里强调的一个经验。
现在大家主流的比较喜欢用的tinypng其实是有损压缩:

https://tinypng.com/
[原文] TinyPNG uses smart lossy compression techniques to reduce the file size of your PNG files…
[翻译] TinyPNG使用智能有损压缩技术,来减少PNG文件的大小…

通过tinypng确实能在尽量少的损失下再减小apk,如果图片资源多或者大的话,效果还是很明显的。
具体减少多少,因为这个处理过程我们是间隔做的,无法准确给出结果,就按200k~500k算吧。

2. png换成jpg

经验发现,一些背景,启动页,宣传页的PNG图片比较大,这些图片图形比较复杂,如果转用有损JPG可能只有不到一半(当然是有损,不过通过设置压缩参数可以这种损失比较小到忽略)。

因为都是大图,所以这种方式能有效减小apk的大小。

3. jpg换成webp

如果png大图转成jpg还是很大,或者想压的更小,而尽量不降低画质,那么可以考虑一下webp。

android 4.0+才原生支持webp, 但是我们的app是兼容2.3+,所以4.0以下的设备将无法看到图片。

1.考虑到我们4.0以下的所有设备比例之和大约在0.44%,非常少
2.4.0以下的设备不会崩溃

我们选择不对4.0以下做webp兼容处理,不显示就不显示。否则,要引入webp相关so文件增大apk大小。

通过把下面四张大图换成webp,webp的quality参数按50配置(据说官方评测75是最佳值),清晰度勉强可以接受,这个值大家具体按产品要求来定。

其中安装jpg转webp工具:

brew install webp

转换命令如下

cwebp-q  input.jpgoutput.webp//
Example:cwebp -q 50 a.jpg a.webp

更多下载

最终,apk减小了188k。

4. 大图缩小

如果经过上面的步骤,依然存在大图的话,说明确实图有点大了,可能真的有点大了!

所以,要考虑的问题是,是否有必要保证如此的大小?能否缩小?如果这方面能减小的话,apk瘦身的效果必然又会上一个档次。

5. 覆盖aar里的一些默认的大图

一些aar库里面包含根本就没有用的图。最典型的是support-v4兼容库中包含一些“可能”用到的图片,实际上在你的app中不会用到。

我没有把所有图都替换掉,只是把几张大一点点的图(选中的那些图)用1×1的图片替换,如果9patch图的话,要做成3×3的9patch图替换。

support库可能还算好的,就怕有些库引用了一些大图而不自知,可以在/build/intermediates/exploded-aar/下的各个aar库的res目录查找检验。

apk减小了18k。

有问题可以加下技术交流群一起来讨论~

6. 删除armable-v7包的so

感谢@杨辉__ ,@kymjs张涛的提醒,armable-v7和armable文件夹可以只保留armable。

当然,armable-v7a的库会对图形渲染方面有很大的改进,因为我们主要是一些业务上动态库,所以删掉无大碍。

apk减小了191k。

7. 微信资源压缩打包

这个方案网上一直在说,之前一直没有需求或者动力实践,在这里感谢一下@裸奔的凯子哥的推荐和交流,他那边的apk可以压小1M,效果还是比较惊人的。
这个步骤我是在后面很多步压缩之后测试的,每个阶段的压缩结果都会有些许出入,所以数据仅供参考。

通过正常压缩,apk包减小了464k。
如果开启7zip,apk包减小了594k。

apk减小了594k。

PS: 关于这个压缩,我集成到了gradle脚本中了,新建了一个Task,大概代码如下:

task compressReleaseApp {
// 在现有release的版本上生成到compressed目录下
def appid = “appid”
def channel = “abcdefghijkl”
def guardJarFile = file(‘…/AndResGuard/andresguard-1.1.jar’)
def guardConfigFile = file(‘…/AndResGuard/config.xml’)
def originApkFile = file(“…/app. a p p i d / b u i l d / o u t p u t s / a p k / r e l e a s e / {appid}/build/outputs/apk/release/ appid/build/outputs/apk/release/{appid}-release- r o o t P r o j e c t . e x t . v e r s i o n N a m e − {rootProject.ext.versionName}- rootProject.ext.versionName{rootProject.ext.versionCode}- c h a n n e l . a p k " ) d e f o u t p u t D i r = f i l e ( " . . / a p p . {channel}.apk") def outputDir = file("../app. channel.apk")defoutputDir=file("../app.{appid}/build/outputs/apk/compressed/”)
def keystoreFile = file(RELEASE_STORE_FILE)
// 开始执行压缩命令
def proc = “java -jar ${guardJarFile} ${originApkFile} -config ${guardConfigFile} -out ${outputDir} -signature ${keystoreFile} ${RELEASE_STORE_PASSWORD} ${RELEASE_KEY_PASSWORD} ${RELEASE_KEY_ALIAS}”.execute();
proc.waitFor();
println “return code: ${ proc.exitValue()}” + “, stderr: ${proc.err.text}” + " stdout: ${proc.in.text}"
}

config开启了7zip, 部分配置如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<issueid=“property”>

<seventzipvalue=“true”/>

<issueid="whitelist"isactive=“true”>

<pathvalue=“com.xxx.yyy.R.drawable.emoji_*”/>

<pathvalue="com.xxx.yyy…
/>

详情参考
原理介绍

8. proguard深度混淆代码

之前为了简单起见,很多包都直接忽略了,现在启动严格模式,把能混淆的都混淆了:

采用微信压缩方案最终效果比较:

apk减小了215k。

PS:混淆后,一定要经过严格测试,有时候甚至很难发现错误,比如我开启严格混淆,用了一段时间之后慢慢发现了两个bug,排除了两个包程序才正常。

9. 深度清理代码和资源

有意思的是,无论何时何地去清理代码和资源,总能有新的发现:

  • 新发现或者新引入的无用图片
  • 这几张图怎么一样
  • 这个类好像没有用
  • 没用的类相关的图片也没用
  • 有些图片可以用着色方案替换
  • 有些图片可以用shape来代替
  • hdpi里的ic_luancher.png好像也可以删掉

apk减小了66k。

10. proguard去符号表

之前为了保留调试信息,我们是在Proguard保留了符号表的:

-keepattributes SourceFile,LineNumberTable

官方渠道我觉得还是尽量保留这个,现在针对推广渠道,只能采用特殊手段,注释这一行。

apk减小了230k。

ps:以后友盟上看推广渠道的bug要辛苦一点,手动上传mapping.txt了。

####11. provided关键字
可以对仅在运行时需要的库设置provided关键字,实际并不被打包:

provided’com.android.support:support-annotations:22.0.0’

我没有发现这样的场景,如果说有的话,就是support-annotations,但是经过后来的测试验证,support-annotations本来就会在release版本中被minifyEnabled掉,所以对support-annotations设置provided是没有意义的。

如果有实际场景,欢迎留言说明,不甚感激。

apk没有减小。

12. 表情包在线化

虽然应用的表情不多,只有50来个,但是如果能把这部分表情放到网上,不仅能有效减小apk大小,还可以方便后期扩展支持:

打包成emoji_v1.zip, 大小是202k。
现在把emoji_v1.zip放到网上,按需下载后使用,最终对比结果如下:

apk减小了193k。

13. 全版本兼容的着色方案

考虑着色方案主要目的是更方便支持多主题,减轻UI工作量,减少工程里一大堆selector文件等,然后才是,顺便的减小一下apk大小。
通过着色方案,我们去除了10多张纯色的按下状态图片和对应的xml等等。

apk减小了15k。

PS: 具体实现可以参考,而我也把它集成到了我的LessCode库中了:DrawableLess.java

14. 去除重复库

发现两个地方:

  • 现在发现七牛的SDK引用了android-async-http-1.4.6.jar,虽然不大,只有95.4k,但是感觉完全可以写一个轻量级的jar,控制在10~20k就足够了,具体可以在现有的网络库上实现。
  • 自己工程使用的是UIL,但是引入的第三方库引用了picasso,两个重复的图片下载库也是完全没用必要的。

现在还没有处理这块,新任务介入,延期优化,敬请期待。

15. 去除无用库

这是一个很基本的点,但是确很容易被人忽视,当你仔细回顾的时候,有一些鸡肋的功能或者库,是几无用处的。不如干脆去掉。

比如,在很早的时候,我就把我们app里的sharesdk删除了,因为对于我们的产品定位和推广来看,这毫无意义。

16. 去除百度统计

这个视具体情况决定。

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

转存中…(img-eexUmHLP-1714962132221)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
universal-apk-builder是一个用于构建通用APKAndroid应用程序包)的工具。它的作用是将一个应用程序的源代码和资源文件转换成可以在不同Android设备上运行的通用APK文件。 通常在开发Android应用程序时,需要为不同的设备和系统版本适配不同的APK文件。这意味着开发人员需要为每个设备和系统版本构建多个APK文件,增加了工作量和开发难度。 universal-apk-builder解决了这个问题。它可以根据输入的源代码和资源文件,自动进行适配和优化,生成一个通用的APK文件。这个通用APK文件可以在大多数Android设备和系统版本上运行,不再需要为每个设备和系统版本构建单独的APK文件。 使用universal-apk-builder的好处是显而易见的。首先,它大大减少开发人员的工作量和开发周期,因为只需要构建一个通用的APK文件即可。其次,通用APK文件的运行效果和性能可以得到更好的保证,因为它经过了适配和优化处理。 然而,与任何工具一样,universal-apk-builder也有一些限制。它可能无法完全适配所有的Android设备和系统版本。在某些特殊情况下,仍然需要构建特定设备和系统版本的APK文件。此外,由于通用APK文件需要兼容多种设备和系统版本,可能会对应用程序的大小和性能产生一些影响。 总体而言,universal-apk-builder是一个实用的工具,可以帮助开发人员简化APK构建过程,提高开发效率。但开发人员仍需根据具体情况和需求来选择是否使用该工具,以及是否进行特定设备和系统版本的适配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值