【朝花夕拾】Android性能篇之(四)Apk打包
前言
APK,即Android Package,是将android程序和资源整合在一起,形成的一个.apk文件。相信所有的Android程序员是在IDE的帮助下,完成打包轻而易举,但对打包流程真正清楚的可能并不多。本章的内容比较简单,也是非常基础的内容,但是对理解android应用的结构却有很大的帮助。笔者写这篇文章的目的,一方面是为了弥补这方面的盲点,回顾和梳理apk打包方面的理论知识点;第二方面,是为了给后续写Android虚拟机知识做铺垫,进而去研究android的性能优化,这也是把这篇文章放到Android性能优化系列文章当中的原因;第三方面,也是为了方便读者理解Android虚拟机的相关内容。
对于在IDE,如Android Studio上操作打包的过程,本文不做演示,对于更深入的源码分析,也不在本文讨论之列,出于前面说到的原因,本文只简单阐述其打包流程,本文主要内容如下:

一、apk构建流程图
以下截图为Google官方提供的详细的apk构建过程图,其中包含了各个环节所用到的工具和中间相关的文件。

apk构建过程(绿色部分为对应环节工具,蓝色部分为相关文件)
二、构建过程中所用工具
如下截图展示了apk构建过程中所使用的部分工具,这些工具大部分都在sdk/build-tools/文件夹下:


代码混淆所用工具

打包所用工具所在的jar包
三、apk打包流程详解
依据如上的流程图和工具图,下面咱们按照流程顺序对其进行讲解。
1、aapt打包资源
- 工具:aapt(Android Asset Package Tool Android资源打包工具)
- 工具路径:sdkpath/build-tools/版本号/aapt.exe和aapt2.exe
- 输入:Android资源文件、AndroidManifest.xml
- 输出: R.java类、二进制的resource.arsc,res文件夹(包括二进制的xml、没被改变的图片和res/raw文件)、二进制的AndroidManifest.xml文件、没有改变的assets文件夹。
Android的资源文件包含了两类:1)assets类资源。该类资源放在工程目录的assets根目录下,存放一些原始文件,这些文件不会被编译为二进制文件,而是被原封不动地打包在apk文件中,同样也不能通过资源ID来查找,不保存在R文件中。2)res类资源,10种目录。这类资源保存在工程目录中的res目录下,包含了animator(属性动画资源)、anim(补间动画资源)、color(对象颜色状态选择资源)、drawable(xml或Bitmap文件的图像资源)、layout(布局文件资源)、menu(程序菜单资源)、mipmap(图标资源,推荐阅读:drawable与mipmap的区别)、raw(不被编译成二进制文件的资源,注意和assets资源的区别,推荐阅读:assets和raw的区别)、values(6种不同的值:数组arrays.xml、颜色值colors.xml、尺寸dimens.xml、字符串strings.xml和样式值styles.xml)、xml(描述应用程序配置信息的资源)。
如下截图展示了R.java的内容,其中包含了各种静态内部类,分别对应了某种资源的类型。

R.java结构图
以R.string类为例,其中展示了字符串名称对应的id值,就是对应在res/values文件夹下,string字符串资源。

R.string结构图
推荐阅读:apk打包安装过程
2、aidl生成跨进程通信的java文件
- 工具:aidl(Android Interface Definition Language安卓接口定义语言)
- 工具路径:sdkpath/build-tools/版本号/aidl.exe
- 输入:aidl后缀的文件,位于工程项目src/main/aidl目录下
- 输出:可用于进程间通信的C/S端java代码,位于build/generated/source/aidl

工程项目中的aidl原始文件

aidl工具处理后生成的java文件
3、Java编译源码
- 工具:javac.exe
- 工具路径:jdk/bin/javac.exe
- 输入:java source文件夹、aapt中生成的R.java文件、aidl生成的java文件、BuildConfig.java文件
- 输出:对于gradle编译,生成的class文件保存在build/intermediates/classes里

BuildConfig.java和R.java文件

输出的class文件
4、proguard代码混淆
完成javac编译之后,一般还会对其进行代码的混淆,其实就是类似于加密的功能,作用就是增加反编译的难度,同时也将一些代码的命名进行了缩短,减少代码占用的空间。推荐阅读:Android代码混淆零基础入门。
- 工具:ProGuard
- 工具路径:sdk/tools/proguard/bin/proguard.bat
- 输入:被编译过的class文件、混淆配置文件proguard-rules.pro
- 输出:被混淆过的.class文件、混淆前后映射文件

5、将所有.class文件转化为classes.dex文件
- 工具:dx.bat
- 工具路径:sdkpath/build-tools/版本号/dx.bat
- 输入:编译后生成的所有.class文件、第三方库和.class文件
- 输出:可以在Android虚拟机上使用的.dex文件
调用dx.bat将所有的class文件转化为classes.dex文件,将二进制码转化为Android虚拟机(Android4.4以前虚拟机是Dalvik,4.4上是Dalvik和ART可以切换、Android5.0及以后是ART)上的字节码、生成常量池、消除冗余数据等。由于Android虚拟机是一种针对嵌入式设备而特殊设计的java虚拟机,所有dex文件与标准的class文件在结构设计上有着很大的区别,当javac将java程序编译成class后,dx工具将所有的class文件整合到一个dex文件中,这样做使得各个类能够共享数据,在一定程度上降低了容易,同时也使文结构更加紧凑,实验表明,dex文件时传统jar文件的50%左右。class文件结构和dex文件结构比对如下(该部分还会在后文讲Android虚拟机时提到):

.class文件和.dex文件结构对比图
6、apkbuilder打包生成apk
- 工具:ApkBuilder类
- 工具路径:sdkpath/tools/lib/sdklib_xxx.jar
- 输入:上一步生成的classes.dex文件,aapt时生成的resources.arsc、被编译后的res文件夹、AndroidManifest.xml,Other Resouces(assets文件夹)
- 输出:.apk文件(Android Package)
7、对apk进行签名
- 工具:apksigner.bat
- 工具路径:sdkpath/build-tools/版本号/apksigner.bat
- 输入:上一步中生成的.apk文件、签名文件(Debug or Release Keystore)
- 输出:签名后的.apk文件
签名是一个apk身份的证明,Android系统在安装apk的时候,首先会检验apk的签名,如果发现签名文件不存在或者校验签名失败,就会拒绝安装。对一个apk文件签名后,apk文件根目录下回增加META-INF目录,该目录下有三个文件:

META-IINF文件夹结构
Android系统就是根据这三个文件的内容对apk文件进行签名验证的:
MANIFEST.MF中包含对apk中除了/META-INF文件夹外所有文件的签名值。

MANIFEST.MF内容截图
CERT.SF是对MANIFEST.MF文件整体签名以及其中各个条目的签名。一般地,如果是使用工具签名,还多包括一项,就是对MANIFEST.MF头部信息签名。

CERT.SF内容截图
CERT.RSA包含用私钥对CERT.SF的签名以及包含公钥信息的数字证书。用一般的文本打开后,会显示乱码。

CETR.RSA内容截图
推荐阅读:Android签名有什么用?
8、zipalign优化
如果是在release mode下,还会对apk进行align,即对签名后的apk进行对齐处理,这种方式是对apk进行整理和优化。
- 工具:zipalign
- 工具路径:sdkpath/build-tools/版本号/zipalign.exe
- 输入:上一步中签名后的apk文件
- 输出:优化后的apk文件
四、APK文件结构
一个apk解压后,其典型的结构如下所示,分别在apk打包流程中appt资源打包、javac编译、签名阶段所产生:

【朝花夕拾】Android性能篇之(四)Apk打包的更多相关文章
- 【朝花夕拾】Android性能篇之(五)Android虚拟机
前言 Android虚拟机的使用,使得android应用和Linux内核分离,这样做使得android系统更稳定可靠,比如程序中即使包含恶意代码,也不会直接影响系统文件:也提高了跨平台兼容性.在And ...
- 【朝花夕拾】Android性能篇之(一)序言及JVM
序言 笔者从事Anroid开发有些年头了,深知掌握Anroid性能优化方面的知识的必要性,这是一个程序员必须修炼的内功.在面试中,它是面试官的挚爱,在工作中,它是代码质量的拦路虎,其重要 ...
- 【朝花夕拾】Android性能篇之(六)Android进程管理机制
前言 Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程.An ...
- 【朝花夕拾】Android性能篇之(三)Java内存回收
在上一篇日志([朝花夕拾]Android性能篇之(二)Java内存分配)中有讲到,JVM内存由程序计数器.虚拟机栈.本地方法栈.GC堆,方法区五个部分组成.其中GC堆是一块多线程的共享区域,它存在的作 ...
- 【朝花夕拾】Android性能篇之(八)来自官网的自白
前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10823372.html],谢谢! Android性能优化无疑是Android中的一个重点,也是 ...
- 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇
前言 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一.Android系统的运行由大量相互独立的进程相互协助来完成的,所以Android进程间通信问题,是做好Andro ...
- Android性能优化系列之apk瘦身
Android性能优化系列之布局优化 Android性能优化系列之内存优化 为什么APK要瘦身.APK越大,在下载安装过程中.他们耗费的流量会越多,安装等待时间也会越长:对于产品本身,意味着下载转化率 ...
- android使用篇(四) 注解依赖注入IOC实现绑定控件
在android使用篇(三) MVC模式中提到一个问题: 1) 视图层(View):一般採用XML文件进行界面的描写叙述,使用的时候能够很方便的引入,可是用xml编写了,又须要在Acitvity声明而 ...
- 【朝花夕拾】Android性能篇之(二)Java内存分配
前言 在内存方面,相比于C/C++程序员,咱们java系程序员算是比较幸运的,因为对于内存的分配和回收,都交给了JVM来处理了,而不需要手动在代码中去完成.有了虚拟机内存管理机制,也就不 ...
随机推荐
- afx.h(78): fatal error C1083: 无法打开包括文件: “new.h”: No such file or directory
vs2015新建mfc工程,编译错误: D:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\afx.h(78): ...
- js/jQuery使用过程中常见问题/已踩过的坑大杂烩
目录 一.jQuery选择器选择选中的或者disabled的选择框时attr函数无效 二.jQuery each函数的break/continue 三.jQuery 获取元素的left会值/left数 ...
- look back to 2018
只写展望怎么行,还是缺一篇总结.2018年几乎没有怎么发朋友圈,需要一些文字记录一下这一年发生的事. 去年的现在,2018年的开端,结束了研一上学期充实的生活,下学期一项艰巨的任务就是完成大项目,一个 ...
- C++入门笔记(一)零碎基础知识
零碎基础知识 一.创建和运行程序 1.使用文本编辑器编写程序,保存为文件,该文件就叫源代码. 2.编译源代码:运行一个程序,将源代码翻译为主机使用的内部语言----机器语言.包含了 编译后程序的文件就 ...
- nginx配置前端代理
#user nobody;worker_processes 1; #error_log logs/error.log;#error_log logs/error.log notice;#error_l ...
- 可视化利器Visdom
可视化利器Visdom 最近在使用Pytorch炼丹,单纯地看命令行输出已经无法满足调试的需求,尝试了facebook开源的visdom,感觉非常优雅,支持numpy和torch 安装 $ pip i ...
- LINUX监控-spotlight
这里连接的user不能是root(spotlight需要一个具有root权限的用户,但是又不允许是root),所以需要给要连接的linux端创建一个有root权限的用户,在linux主机创建了root ...
- Vue知识点总结
1.属性名已$开头的都是内部提供的属性 2.为什么使用事件修饰符的原因:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节 3.v-if 如果值为false,元素在页面中不存在:值为t ...
- 使用COOKIE实现登录 VS 使用SESSION实现登录
注:本文使用的代码基于PHP,其他语言逻辑同理. 一:使用COOKIE实现登录验证 使用cookie实现登录的方式,主要通过一些单向的加密信息进行验证.比如admin用户登录了之后,服务端生成一个co ...
- Fence Repair POJ - 3253 (贪心)
Farmer John wants to repair a small length of the fence around the pasture. He measures the fence an ...