今日长缨在手,何时缚住苍龙。这篇文章主要讲述朝花夕拾Android性能优化篇之Apk打包相关的知识,希望能为你提供帮助。
APK,即android Package,apk打包是将android程序和资源整合在一起,形成的一个.apk文件。相信所有的Android程序员是在IDE的帮助下,完成打包轻而易举,但对打包流程真正清楚的可能并不多。要更好地理解android性能优化,就要对Android虚拟机有一定的了解,而要比较好地理解Android虚拟机,就需要清楚apk的打包流程。前言
转载请声明,转自【https://www.cnblogs.com/andy-songwei/p/9721337.html】,谢谢!
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文件夹。
如下截图展示了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文件
文章图片
.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)
- 工具:apksigner.bat
- 工具路径:sdkpath/build-tools/版本号/apksigner.bat
- 输入:上一步中生成的.apk文件、签名文件(Debug or Release Keystore)
- 输出:签名后的.apk文件
文章图片
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签名有什么用?
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上传GitHub
- Fabric-Crashlytics-Android 注意点
- react-native-baidu-map 在Android上的集成
- Android aspectJ Aop
- C# 中 DapperRow 数据解析
- Cannot read property 'appendChild' of null
- android studio3.1 添加闪屏页面(启动欢迎界面)(例子简单无BUG)
- pandas的apply操作