Android Studio 2.2包含了APK Analyzer,通过它我们能够直观地看到APK的组成。使用APK Analyzer不仅能够减少你花在debug上的时间,而且还能减少你的APK大小。使用APK Analyzer,你能够实现:
- 查看APK中文件的绝对大小和相对大小。(译注:相对大小指的是该文件占整个APK大小的百分比)
- 理解DEX文件的组成。(译注:能看到DEX文件中包含了哪些类)
- 快速查看APK中文件的最终版本(比如AndroidManifest.xml)。(译注:AndroidManifest.xml、resources.arsc本来是二进制形式显示的,APK Analyzer能够解析并显示这些文件的内容)
- 对比两个APK。(译注:新版APK和旧版APK之间文件大小的差异)
这里有3种方法访问APK Analyzer:
- 拖拽APK到Android Studio的编辑窗口。
- 切换到Project视图,并且双击APK文件。
- 在菜单栏中选择Build > Analyzer APK,并且选择APK。
注意:当使用APK Analyzer分析debug的APK,请使用Build > Build APK生成的APK。点击Run将会生成Instant Run的APK。APK Analyzer不能分析通过Instant Run生成的APK,判断APK是否是Intant Run生成的可以通过看APK中是否有instant-run.zip文件。
译注:APK Analyzer是让我们更有效地制定减包方案的实用工具,它能够让我们发现使得APK变大的元凶。
查看文件和大小信息
APK就是一个zip包。APK Analyzer显示每个文件或目录作为一个实体,实体的层级说明了APK文件的结构。
如图1,APK Analyzer对每个实体显示了raw file size和download file size。Raw File Size表示实体在磁盘中解压后的大小,而Download Size表示实体在Google Play中压缩后的大小。% of Total Download Size表示实体的download size占APK总的download size的百分比。
译注:图1中,最上面的5.8M是指APK在磁盘中的大小,而4.9M是指从Google Play中下载的大小。
图1:在APK Analyzer中的文件大小
译注:通过查看各个目录或文件的大小,我们能发现APK中哪个区域的文件太大了,比如如果dex太大,我们是不是引入了重复功能的第三方库(比如Glide和Fresco),或者抽取出一个精简的第三方库(精简ffmpeg库);如果res目录太大,我们可以看看哪些图片过大了,需要通过tinypng压缩,或者用webp代替。
查看AndroidManifest.xml
如果项目中包含了多个AndroidManifest.xml或者包含提供manifest文件的library,在APK中他们将被合并为一个manifest文件。在APK中manifest文件是普通的二进制文件,但是在APK Analyzer中查看manifest文件,该文件是以XML形式显示的。这种显示形式让我们能理解应用中的任何变化。比如,你能看到library中的AndroidManifest.xml是怎么合入最后的AndroidManifest.xml的。
另外,这种显示形式提供了lint的能力,会在右上角显示警告、错误提示。图2显示了manifest文件的错误提示。
图2:manifest文件的一个错误
查看代码和资源实体
不同的构建任务会改变APK文件最后的实体。比如混淆压缩规则能改变你最后的代码和图片资源。在APK Analyzer中能够快速查看文件的最终版本:点击实体,就能在下面看到文件的内容,包含文字和图片实体的预览。
图3:最终图片资源的预览
APK Analyzer也能展示文本或二进制文件。比如点击resources.arsc能够让你看到针对配置特定的值(例如一个字符串资源的特定语言的翻译)。如图4,你能看到每个字符串资源的翻译。
图4:翻译的字符串资源预览
查看DEX文件
APK Analyzer的DEX文件浏览器让你能够快速了解DEX文件的信息。我们能看到类、包、总的引用和声明个数,这些信息能够帮助我们决定是否使用multi-dex或者移除依赖使得满足64K方法数限制。
图5展示了一个中等大小的APP(方法数接近64K)。每个包、类、方法都列有Defined Method和Referenced Method。Referenced Method列是DEX文件中引用的全部方法,它包含了你定义的方法、依赖的library、定义在标准Java和Android包中的方法。Defined Method列只包含了定义在DEX文件中方法,因此它是Referenced Method方法的子集。注意当你引入一个依赖,在依赖中定义的方法会包含在Defined Method和Referenced Method中。还要注意,混淆压缩也会改变DEX文件的内容。
图5:一个使用了multi-dex的应用
比较APK文件
APK Analyzer能比较两个不同APK中各个实体的大小。这对于我们了解为何你的APP相比上个版本变大了是很有用的。
在发布一个新版APK之前,在APK Analyzer中导入你即将发布的APK。在右上角点击Compare With,选择上一个版本的APK,点击OK。然后就会出现类似图6的对话框,允许你比较之间的差别。
图6显示了一个APP的debug和release包的差别,不同的编译类型会导致实体的不同。
译注:Old Size是先选择的APK,New Size是后选择的APK。
图6:debug和release的APK之间的差别