apk瘦身之旅

我们完成一个app后,都需要生成一个apk,然后上线,而apk的大小也一定程度的影响了用户是否愿意下载你的这个app,所以也就有了apk瘦身这门艺术。

目录

  • apk的结构

  • 图片压缩

    • 导入矢量图

    • 适配问题

    • Tint 着色器

  • 动态库移除

    • so库的相关知识点

    • ABI

  • 结束语

apk的结构

既然要对一个apk瘦身,首先我们就得知道apk格式的文件内容。实际上一个apk文件就是一个zip包,我们只需要将后缀改为zip,然后进行解压就可以看到里面的内容了。下面我们来看下它里面的文件以及作用:

apk包含以下目录:

  • assets/: 包含了应用的资源,这些资源能够通过AssetManager对象获得。

  • lib/: 包含了针对处理器层面的被编译的代码。这个目录针对每个平台类型都有一个子目录,比如armeabi, armeabi-v7a, arm64-v8a, x86, x86_64和mips。

  • res/: 包含了没被编译到resources.arsc的资源。

  • META-INF/: 包含CERT.SF和CERT.RSA签名文件,也包含了MANIFEST.MF文件。(译注:校验这个APK是否被人改动过)

apk包含以下文件:

  • classes.dex: 包含了能被Dalvik/Art虚拟机理解的 dex 文件格式的类。

  • resources.arsc: 包含了被编译的资源。该文件包含了res/values目录的所有配置的 xml 内容。打包工具将 xml 内容编译成二进制形式并压缩。这些内容包含了语言字符串和styles,还包含了那些内容虽然不直接存储在resources.arsc文件中,但是给定了该内容的路径,比如布局文件和图片。所以又叫 资源映射表

  • AndroidManifest.xml: 包含了主要的Android配置文件。这个文件列出了应用名称、版本、访问权限、引用的库文件。该文件使用二进制 xml 格式存储。(译注:该文件还能看到应用的minSdkVersion, targetSdkVersion等信息)

好的,现在我们已经知道apk到底是个什么东东了,接下来我们开始一步步对这些内容进行瘦身处理。

图片压缩

我们都知道,一个apk会使用大量的图片,如果图片这块能够压缩下,那效果还是非常可观的。

如下图,我们在项目中经常会用到这样的套图。

明明只是一种图片,而我们却因为大小和颜色,需要这样的一组,显然很占大小,那有没有什么方式优化下呢?

答案是有的。

谷歌的AS为我们提供了一个名为 Vector Asset Studio 的工具,可以帮助我们添加内置Material图标以及将本地的SVG(Scalable Vector Graphics 可缩放矢量图)等格式作为矢量图资源导入到项目中,会在drawable目录下生成一个根节点为vector的xml文件,而且矢量图的大小也更小,是不是非常棒啊!那下面我们来看看怎么实现的。

导入矢量图

首先我们在AS中运行Vector Asset Studio,步骤是:右键点击你工程中的res文件夹,然后选择 New --> Vector Asset,此时会弹出下面对话框,选择图中标记的对应操作即可导入内置Material图标或者SVG矢量图。

但是上面这种方式只能一张张导入图片,显然很麻烦。那有没有更好的方式了?实际上我们之所以要用这个工具导入svg图片,而不是直接将svg图片复制到drawable中,是因为安卓不支持svg,需要工具转换下,所以我们可以使用svg2vector这个第三方库进行批量转换,然后直接复制到drawable中即可,转换命令如下:

java -jar svg2vector-cli-1.0.0.jar -d . -o a -h 20 -w 20

-d 指定svg文件所在目录 -o 输出android vector图像目录 -h 设置转换后svg的高 -w 设置转换后svg的宽

适配问题

因为矢量图是在Android 5.0(API21)才开始支持的,所以这个地方我们还需要适配下。如果不适配,你的最小minSdkVersion版本又小于21,则会自动在每个drawable目录下生成对应的png图片,反而会使apk包变大,所以这里一定要注意了。我们有下面两种方式进行适配:

方式一:生成 png 格式的图片

这种方式是在drawable文件中生成对应的png,不过我们可以指定只生成哪几个。例如如下配置

我们可以在项目的build.gradle中进行如下配置,即可在指定的drawable文件中生成对应的png格式图片。

方式二:支持库

还一种方式就是使用支持库,支持库的版本需要23.2或者更高,也是在项目的build.gradle中进行配置,如下:


这种适配方式使用图片的时候,需要用 app:srcCompat 属性,而不是 android:src,如下:

通过这个方式只是解决了不同大小需要多张图片的问题,但是还需要有不同颜色的图片。这个我们怎么处理呢?不要急,这个问题谷歌工程师也为我们准备了一个工具,它就是Tint着色器。

Tint 着色器

一般我们矢量图都是使用黑色,然后由Tint着色器去修改颜色,直接在xml中使用即可,如下:

在java代码中,我们可以通过DrawableCompat去设置,如下:

那如果想要实现按键效果,通过 Tint 也能实现吗?答案是可以的。

首先我们需要创建两个选择器,一个是 drawable 选择器,一个是 color 选择器,如下:

然后就可以直接使用了,如下:

总的来说使用Tint找色器去修改矢量图的颜色还是蛮简单的吧。

通过矢量图这个方式,我们就能够减小使用图片的总大小,从而减小apk的大小。

瘦身不是一蹴而就的,所以我们接着减。

动态库移除

so库的相关知识点

说到so库,相信大部分人都有使用过,但是却不知道它到底是什么。其实so库就是由ndk编译出来的动态库。

那我们为什么要把so文件分别放在armeabi、arm64-v8a、armeabi-v7a、x86、x86_64这些文件中呢?

主要是因为我们的app运行在不同的手机中,而so库是由c\c++编译的,不是跨平台的,所以不同平台(不同CPU)需要使用不同的so库。那不同的文件是什么意思呢?我们接着往下看。

ABI

ABI 是应用程序二进制接口简称(Application Binary Interface),定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统上,每一个CPU架构对应一个ABI,即:armeabi,armeabi-v7a,arm64-v8a,x86,x86_64,mips,mips64。

ABI

Supported Instruction Set(s)

armeabi

ARMV5TE and later,Thumb-1

armeabi-v7a

armeabi,Thumb-2,VFPv3-D16,Other,optional

arm64-v8a

AArch-64

x86

x86(IA-32),MMX,SSE/2/3,SSSE3

x86_64

x86-64,MMX,SSE/2/3,SSE3,SSE4.1,SSE4.2,POPCNT

mips

MIPS32r1 and later

mips64

MIPS64r6

各版本分析如下:

  • mips / mips64:极少用于手机可以忽略

  • x86 / x86_64:x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现 对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的

  • armeabi:ARM v5 这是相当老旧的一个版本,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈

  • armeabi-v7a:ARM v7 目前主流版本

  • arm64-v8a:64位支持

所以现在我们一般只要在项目的build.gradle中适配ARM v7就行了,如下:

结束语

好的,今天我们就暂时介绍到这儿,瘦身之旅长路漫漫,还有的方式我们下次分享。

未完待续。。。

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

推荐阅读更多精彩内容

  • APK瘦身可以为我们带来什么好处? 提高传输及编译效率。无论是上传应用商店还是公司内部传输以及我们自己编译,越小的...
    在心的末端阅读 928评论 0 2
  • 随着app的业务复杂度越来越高、资源文件越来越多,我们的app安装包apk文件也就越来越大,而过大的apk文件往往...
    jackting阅读 8,099评论 1 2
  • apk分析 让我们在瘦身前先瞅一眼apk是什么,里面有啥:这里是用的工具是Android studio里,buil...
    刘喵喵嗷呜阅读 302评论 0 0
  • 了解Apk结构 APK 文件就是一个Zip格式的文件,其中包含构成应用的所有文件。这些文件包括 Java 类文件、...
    zcwfeng阅读 283评论 0 2
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,535评论 28 53