Android APK 打包过程 MD
Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
Android APK 打包流程 MD
目录
APK 的打包流程
整体流程
资源的编译和打包
资源ID
资源索引
概况
具体打包过程
aapt阶段
aidl阶段
Java Compiler阶段
dex阶段
apkbuilder阶段
Jarsigner阶段
zipalign阶段
APK 的打包流程
Android的包文件APK分为两个部分:代码和资源
,所以打包方面也分为资源打包和代码打包两个方面,这篇文章就来分析资源和代码的编译打包原理。
Android打包流程详图:
整体流程
APK整体的的打包流程如下图所示:
具体说来:
- 通过
AAPT
工具进行资源文件(包括AndroidManifest.xml、布局文件、各种xml资源等)的打包,生成R.java文件。 - 通过
AIDL
工具处理AIDL文件,生成相应的Java文件。 - 通过
Javac
工具编译项目源码,生成Class文件。 - 通过
DX
工具将所有的Class文件转换成DEX文件,该过程主要完成Java字节码转换成Dalvik字节码,压缩常量池以及清除冗余信息等工作。 - 通过
ApkBuilder
工具将资源文件、DEX文件打包生成APK文件。 - 利用
KeyStore
对生成的APK文件进行签名。 - 如果是正式版的APK,还会利用
ZipAlign
工具进行对齐处理,对齐的过程就是将APK文件中所有的资源文件举例文件的起始距离都偏移4字节的整数倍,这样通过内存映射访问APK文件的速度会更快。
上述流程都是Android Studio在编译时调用各种编译命令
自动完成的,具体说来,如下所示:
1、创建Android工程。
android create project \
-n packageTest2 \
-a MainActivity \
-k com.package.test2 \
-t android-23 \
-p ./PackageTest2
2、编译R文件
aapt package \
-f \
-J ./gen \
-M ./AndroidManifest.xml \
-S ./res/ \
-I /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar
3、编译源代码文件
javac -source 1.6 \
-target 1.6 \
-cp /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar \
./src/com/packtest/test1/MainActivity.java ./src/com/packtest/test1/R.java \
-d ./gen/classes
4、编译DEX文件
dx --dex \
--verbose \
--output ./gen/dex/packtest1.dex
./gen/classes/
5、生成APK文件
aapt package
-f \
-J ./gen \
-M ./AndroidManifest.xml \
-S ./res/ \
-I /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar \
-F ./output/res.apk
6、APK文件对齐
zipalign -v -p 4 packagetest_unsigned.apk packagetest_aligned_unsigned.apk
7、APK签名
apksigner sign --ks my-release-key.jks my-app.apk
以上便是APK打包的整个流程,我们再来总结一下:
- 除了assets和res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理;
- 除了assets资源之外,其它的资源都会被赋予一个资源ID;
- 打包工具负责编译和打包资源,编译完成之后,会生成一个resources.arsc文件和一个R.java,前者保存的是一个资源索引表,后者定义了各个资源ID常量。
- 应用程序配置文件AndroidManifest.xml同样会被编译成二进制的XML文件,然后再打包到APK里面去。
- 应用程序在运行时通过AssetManager来访问资源,或通过资源ID来访问,或通过文件名来访问。
理解了整体的流程,我们再来看看具体的细节。
资源的编译和打包
在分析资源的编译和打包之前,我们先来了解一下Android程序包里有哪些资源。
我们知道Android应用程序的设计也是代码与资源相分离
的,Android的资源文件可以分为两大类:
assets:assets资源放在主工程assets目录下,它里面保存一些原始的文件,可以以任何方式来进行组织,这些文件最终会原封不动的被打包进APK文件中。
获取asset资源也十分简单,如下所示:
InputStream is = getAssets.open("fileName");
res:res资源放在主工程的res目录下,这类资源一般都会在编译阶段生成一个资源ID供我们使用。
res资源包含了我们开发中使用的各种资源,具体说来:
- animator
- anim
- color
- drawable
- layout
- menu
- raw
- values
- xml
这些资源的含义大家应该都很熟悉,这里就不再赘述。
上述9种类型的资源文件,除了raw
类型资源,以及Bitmap文件的drawable
类型资源之外,其它的资源文件均为文本格式的XML
文件,它们在打包的过程中,会被编译成二进制格式的XML文件。这些二进制格式的XML文件分别有一个字符串资源池,用来保存文件中引用到的每一个字符串,包括XML元素标签、属性名称、属性值,以及其它的一切文本值所使用到的字符串。这样原来在文本格式的XML文件中的每一个放置字符串的地方在二进制格式的XML文件中都被替换成一个索引到字符串资源池的整数值,这写整数值统一保存在
R.java
类中,R.java会和其他源文件一起编译到APK中去。
前面我们提到xml编写的Android资源文件都会编译成二进制格式的xml文件,资源的打包都是由AAPT
工具来完成的,资源打包主要有以下流程:
- 解析
AndroidManifest.xml
,获得应用程序的包名称,创建资源表。 - 添加被引用资源包,被添加的资源会以一种资源ID的方式定义在
R.java
中。 - 资源打包工具创建一个
AaptAssets
对象,收集当前需要编译的资源文件,收集到的资源保存在AaptAssets对象对象中。 - 将上一步AaptAssets对象保存的资源,添加到资源表
ResourceTable
中去,用于最终生成资源描述文件resources.arsc
。 - 编译
values
类资源,这类资源包括数组、颜色、尺寸、字符串等值。 - 给bag、style、array这类资源分配资源ID。
- 编译xml资源文件,编译的流程分为四步:① 解析xml文件 ② 赋予属性名称资源ID ③ 解析属性值 ④ 将xml文件从文本格式转换为二进制格式。
- 生成资源索引表
resources.arsc
。
资源ID
每个Android项目里都有有一个R.java文件,如下所示:
public final class R {
//...
public static final class anim {
public static final int abc_fade_in=0x7f010000;
}
public static final class attr {
public static final int actionBarDivider=0x7f020000;
}
public static final class string {
public static final int actionBarDivider=0x7f020000;
}
//...
}
每个资源项后的整数就是资源ID,资源ID是一个4字节的无符整数,如下所示:
- 最高字节是Package ID表示命名空间,标明资源的来源,Android系统自己定义了两个Package ID,系统资源命名空间:0x01 和 应用资源命名空间:0x7f。
- 次字节是Type ID,表示资源的类型,例如:anim、color、string等。
- 最低两个字节是Entry ID,表示资源在其所属资源类型中所出现的次序。
资源索引
上面提到,最终生成的是资源索引表resources.arsc
,Android正是利用这个索引表根据资源ID进行资源的查找,为不同语言、不同地区、不同设备提供相对应的最佳资源。查找是通过Resources和AssetManger来完成的,这个我们下面会讲。
resources.arsc 是一个编译后的二进制文件,在Android Stduio里打开以后是这样的,如下所示:
可以看到resources.arsc里存放了各类资源的索引参数和配置信息。
resources.arsc的文件格式如下所示:
注:整个文件都是有一系列chuck(块)构成的,chuck是整个文件的划分单位,每个模块都是一个chuck,chuck最前面是一个ResChunk_header的结构体,用来描述整个chunk的信息,更多关于索引表格式的细节,可以查阅源码:
Android APK 打包过程 MD的更多相关文章
- 【转】android Apk打包过程概述_android是如何打包apk的
最近看了老罗分析android资源管理和apk打包流程的博客,参考其他一些资料,做了一下整理,脱离繁琐的打包细节和数据结构,从整体上概述了apk打包的整个流程. 流程概述: 1.打包资源文件,生成 ...
- android Apk打包过程概述_android是如何打包apk的
流程概述:1.打包资源文件,生成R.java文件2.处理aidl文件,生成相应java 文件3.编译工程源代码,生成相应class 文件4.转换所有class文件,生成classes.dex文件5.打 ...
- Aandroid 解决apk打包过程中出现的“Certificate for <jcenter.bintray.com> doesn't match any of the subject alternative names: [*.aktana.com, aktana.com]”的问题
有时候,apk打包过程中会出现“Certificate for <jcenter.bintray.com> doesn't match any of the subject alterna ...
- Android APK安装过程学习笔记
1.什么是APK APK,即Android Package,Android安装包.不同平台的安装文件格式都不同,类似于Windows的安装包是二进制的exe格式,Mac的安装包是dmg格式.APK可以 ...
- Unity安卓apk打包过程
前言:对于Unity开发小白来说,Android打包无疑是个头痛的问题,所以我总结了 Unity安卓APK的打包过程 第一步:下载对应版本的Android Platform 第二步:安装JDK并配置J ...
- android基础-Apk打包过程(了解)
此文来源于<Android软件安全与逆向分析> 一.打包资料文件,生成R.java文件. 二.处理aidl文件,生成相应的Java文件. 三.编译工程源代码,生成相应的class文件. 四 ...
- Android学习--apk打包过程
1. 使用aapt工具,给所有的res目录下的资源文件生成对应的id,id会被放进R.java文件中 2. JavaC编译器,将所有Java文件转换为Class文件,其中,内部类会分别生成.class ...
- Android APK安装过程介绍
课题路径:从Myfile中点击应用进行安装,到安装完成,过程分析 思想方法:在研究PreloadInstaller的时候我们直接从整个apk的文件结构入手,由整体到部分的分析:但现在整个PMS非常庞大 ...
- Android APK打包流程
简单build流程图 官网给了我们一张非常简单的编译.打包.apk生成内容以及签名的图片.图片大体介绍了从Project到运行到设备或者模拟器的一个大体流程,我们也从中看到一个完整的apk包含如下内容 ...
随机推荐
- js常用函数整理
类型转换:parseInt\parseFloat\toString 类型判断:typeof;eg:if(typeof(var)!="undefined")\isNaN 字符处理函数 ...
- Java8实战系列一
从java7到java8,最主要的变化可以总结为 □Lambda表达式 □ 方法引用 □流和默认方法 让我们通过一个小例子感受一下 情景 1 集合对象排序 (对list中的苹果按照重量排序) Coll ...
- OpenLDAP在win2008上安装配置
业务需要,将企业员工信息统一管理,OpenLdap是目录数据库和一套访问协议组成的系统,适合使用,它有以下特点: LDAP的结构用树来表示 C/S模型,Server用户存储数据,Client为操作目录 ...
- 里氏代换原则(Liskov Substitution Principle,LSP)
第一种定义: 如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换为o2,程序P的行为没有发生变化,那么类型S是类型T的子类型. 第二种定义: 所有引 ...
- Linux下apache支持PHP配置
https://www.cnblogs.com/qiuxiao/p/6815350.html https://www.cnblogs.com/polestar/p/6086552.html
- POJ 3050 Hopscotch【DFS带回溯】
POJ 3050 题意: 1.5*5的方阵中,随意挑一格,记住这个格子的数字 2.可以上下左右走,走5次,每走一次记录下所走格子的数字 3.经过以上步骤,把所得6个数字连起来,形成一串数字.求共可以形 ...
- Mysql 双主架构配置从复制
引用自:https://blog.csdn.net/deeplearnings/article/details/78398526 https://www.cnblogs.com/ygqygq2/p/6 ...
- Python 2维数组90度旋转
一.二维列表 a = [[col for col in range(4)] for row in range(4)] [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3] ...
- BZOJ1079 [SCOI2008]着色方案 动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1079 题目概括 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的 ...
- P3144 关闭农场 并查集 反向
FJ和他的奶牛们正在计划离开小镇做一次长的旅行,同时FJ想临时地关掉他的农场以节省一些金钱. 这个农场一共有被用M条双向道路连接的N个谷仓(1<=N,M<=3000).为了关闭整个农场,F ...