关于APK瘦身值得分享的一些经验

从APK的文件结构说起

APK在安装和更新之前都需要经过网络将其下载到手机,如果APK越大消耗的流量就会越多,特别是对于使用移动网络的用户来讲,消耗流量越多就代表需要花更多的钱去购买流量。同时一些第三方应用商城也会对上传的APK大小有限制,所以为了能够让产品能够更受商城和用户欢迎,APK瘦身是第一步,更小的APK标示着更多地用户愿意去下载和体验。

为了能够减小APK的大小,首先需要知道APK由哪些部分构成,然后针对每个部分做相应的优化工作,下图是一个APK解压后的文件结构:

图一:APK结构
图一:APK结构

各文件的介绍如下:

  • classes.dex:classes.dex是java源码编译后生成的java字节码文件。但由于Android使用的dalvik虚拟机与标准的java虚拟机是不兼容的,dex文件与class文件相比,不论是文件结构还是opcode都不一样。目前常见的java反编译工具都不能处理dex文件。Android模拟器中提供了一个dex文件的反编译工具,dexdump。用法为首先启动Android模拟器,把要查看的dex文件用adb push上传的模拟器中,然后通过adb shell登录,找到要查看的dex文件,执行dexdump xxx.dex。另,有人介绍到Dedexer是目前在网上能找到的唯一一个反编译dex文件的开源工具,需要自己编译源代码。

  • resources.arsc:编译后的二进制资源文件

  • AndroidManifest.xml:该文件是每个应用都必须定义和包含的,它描述了应用的名字、版本、权限、引用的库文件等等信息,如要把apk上传到Google Market上,也要对这个xml做一些配置。在apk中的AndroidManifest.xml是经过压缩的,可以通过AXMLPrinter2工具解开,具体命令为:java -jar AXMLPrinter2.jar AndroidManifest.xml

  • proguard.cfg:代码混淆配置文件;

  • project.properties:标示APK的target sdk和依赖关系,这里的依赖关系指示的是该APK依赖到了哪些工程;

  • assets:assets目录可以存放一些配置文件(比如webview本地资源、图片资源等等),这些文件的内容在程序运行过程中可以通过相关的API获得。具体的方法可以参考SDK中的例子:在sdk的 \SDK\1.6\android-sdk-windows-1.6_r1\platforms\android-1.6\samples\ApiDemos 例子中,有个com.example..android.apis.content 的例子,在这个例子中他把一个text文件放到工程的asset目录下,然后把这个txt当作普通文件处理。处理的过程在ReadAsset.java中。同理,asset也可以放置其他文件。

  • lib:lib目录下的子目录armeabi存放的是一些so文件。这个地方多讲几句,都是在开发过程中摸索出来的。eclipse在打包的时候会根据文件名的命名规则(lib****.so)去打包so文件,开头和结尾必须分别为“lib”和“.so”,否则是不会打包到apk文件中的。其他非eclipse开发环境没有测试过。如果你是用SDK和NDK开发的话,这部分很重要,甚至可以通过把一些不是so文件的文件通过改名打包到apk中,具体能干些什么那就看你想干什么了,呵呵呵!

  • META-INF:META-INF目录下存放的是签名信息,用来保证apk包的完整性和系统的安全。在eclipse编译生成一个apk包时,会对所有要打包的文件做一个校验计算,并把计算结果放在META-INF目录下。这就保证了apk包里的文件不能被随意替换。比如拿到一个apk包后,如果想要替换里面的一幅图片,一段代码, 或一段版权信息,想直接解压缩、替换再重新打包,基本是不可能的。如此一来就给病毒感染和恶意修改增加了难度,有助于保护系统的安全。

  • res:res目录存放资源文件。包括图片、字符串、raw文件夹下面的音频文件、各种xml文件等等。

从图一可知,APK中classes.dex、lib、资源文件是大头,APK瘦身主要就是优化这三类,关于这三种类型的文件比较成熟的优化方法有:

  • classes.dex:通过代码混淆,删掉不必要的jar包和代码实现该文件的优化;

  • lib:一个硬件设备对应一个架构(mips、arm或者x86),只保留与设备架构相关的库文件夹(主流的架构都是arm的,mips属于小众,默认也是支持arm的so的,但x86的不支持),这样可以大大降低lib文件夹的大小;

  • 资源文件:通过Lint工具扫描代码中没有使用到的静态资源。

上面介绍的三种类型文件的优化方案的确能够在一定程度上减小APK的大小,但在最近做项目的过程中经过研究发现还可以更进一步优化APK的大小,具体方案如下:

  • 多分辨率适配:我之前写过一篇关于多分辨率适配的文章Android多分辨率适配经验总结,一套图、一套布局,多套dimens.xml文件,在使用最小资源的情况下搞定多分辨率适配;

  • 预置数据:和游戏一样,程序和数据分离,进入模块时下载预置数据(下载的策略需要注重用户体验,在需要使用数据的地方下载);

  • 图片资源:使用tinypng和webP,下面详细介绍图片资源优化的方案。

图片资源优化攻略

图片资源的优化原则是:在不降低图片效果、保证APK显示效果的前提下缩小图片文件的大小。

使用tinypng优化大部分图片资源:

tinypng是一个支持压缩png和jpg图片格式的网站,通过其独特的算法(通过一种叫“量化”的技术,把原本png文件的24位真彩色压缩为8位的索引演示,是一种矢量压缩方法,把颜色值用数值123等代替。)可以实现在无损压缩的情况下图片文件大小缩小到原来的30%-50%。压缩率和压缩后的效果如下:

图二:tinypng图片压缩率展示
图二:tinypng图片压缩率展示
图上:tinpng图片压缩前后效果对比
图上:tinpng图片压缩前后效果对比

上面的图片对比举例不太好,不过可以看到压缩前后图片效果并没有变化,需要说明的是:tinypng支持png和jpg图片的压缩,并且也支持9图的压缩。

tinypng的缺点是在压缩某些带有过渡效果(带alpha值)的图片时,图片会失真,这种图片可以将png图片转换为下面介绍的webP格式,可以在保证图片质量的前提下大幅缩小图片的大小。

tinypng提供了开放接口供开发者开发属于自己的压缩工具,不过这是付费服务,对于普通用户来说,tinypng为每个用户提供的每月图片免费压缩数量已经足够了。

使用webP图片格式:

WebP是谷歌研发出来的一种图片数据格式,它是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。目前很多公司已经将webP技术运用到Android APP中,比如FaceBook、腾讯、淘宝。webP相比于png最明显的问题是加载稍慢,不过现在的智能设备硬件配置越来越高,这都不是事儿。

假如你打算在 App 中使用 WebP,除了 Android4.0 以上提供的原生支持外,其他版本以可以使用官方提供的解析库webp-android-backport编译成so使用。

通常UI提供的图片都是png或者jpg格式,我们可以通过智图或者isparta将其它格式的图片转换成webP格式,isparta可实现批量转换,墙裂推荐!

使用tintcolor实现按钮反选效果:

通常按钮的正反旋图片我们都是通过提供一张按钮正常图片和一张按钮反选图片,然后通过selector实现,两张图片除了alpha值不一样外其它的内容都是重复的,在Android 5.0及以上的版本可以通过tintcolor实现只提供一张按钮的图片,在程序中实现按钮反选效果,前提是图片的内容一样,只是正反选按钮的颜色不一样。

参考资料

本文重点讲述图片资源的优化,关于APK瘦身可以从多个方面入手,下面是一些关于APK瘦身值得阅读的文章,本文也作了一些参考。只要用心专研,APK的大小肯定会控制下来的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,336评论 25 707
  • 最近几周一直在研究如何为APK瘦身,折腾了很久,是时候写篇博客总结一下了,虽然已经准备了下周一要在客户端周会分享用...
    风清袖一阅读 1,037评论 1 10
  • 本文来自尚妆Android团队青峰发表于尚妆博客 APK瘦身探索 最近几周一直在研究如何为APK瘦身,折腾了很久,...
    尚妆产品技术刊读阅读 1,776评论 1 23
  • 本文会不定期更新,推荐watch下项目。如果喜欢请star,如果觉得有纰漏请提交issue,如果你有更好的点子可以...
    天之界线2010阅读 18,170评论 19 153
  • 话题 #讨论芈月传# 【少侠】枫丹白露·1+1 2016/1/9 15:32:38 成功的女人背后有一群好男人 【...
    青年西米阅读 353评论 0 5