Android App 构建流程分析

我们平时在android studio中点击run ,就能把代码编译成一个apk文件并安装到手机上。那么这个过程中都具体发生了什么 ?我们是怎么把代码和资源文件打包成一个apk文件,并安装到手机上的呢 ? 今天就详细研究一下这个流程 。

Apk构建基本流程

build-simplified.png

上图是Android官方提供的打包简略流程图。清晰地展示了一个Android Project经过编译和打包后生成apk文件,然后再经过签名,就可以安装到设备上

我们将一个实际的apk文件后缀改为zip并解压后,得到的内容如下

apk_component_1.png

和上图的描述一致。apk包内容包括:

  • classes.dex…
  • resources.arsc
  • assets
  • res
  • AndroidManifest.xml
  • META-INF

其中:

  1. res中图片和raw文件下内容保持原样,res中其他xml文件内容均转化为二进制形式;assets文件内容保持原样
  2. res中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类

在看下这张图 ,android apk构建详细流程图

QQ截图20161230105534.png

打包步骤:

1. 通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样) ,详细步骤如下

  • 检查AndroidManifest.xml,主要做一些检查并使用parsePackage初始化并设置一些attribute,比如package, minSdkVersion, uses-sdk。

  • 添加被引用资源包使用table.addIncludedResources(bundle, assets)添加被引用资源包,比如系统的那些android:命名空间下的资源。

  • 收集资源文件,处理overlay(重叠包,如果指定的重叠包有和当前编译包重名的资源,则使用重叠包的):

  • 将收集到的资源文件加到资源表(ResourceTable)对res目录下的各个资源子目录进行处理,函数为makeFileResources:makeFileResources会对资源文件名做合法性检查,并将其添加到ResourceTable内。

  • 编译values资源并添加到资源表,在上一步添加过程中,其实并没有对values资源进行处理,因为values比较特殊,需要经过编译之后,才能添加到资源表中。

  • 给bag资源分配id,在继续编译其他资源之前,我们需要先给bag资源(attrs,比如orientation这种属性的取值范围定义的子元素)分配id,因为其他资源可能对它们有引用。

  • 编译xml资源文件,最后我们终于可以编译xml文件了,因为我们已经为它准备好了一切可能引用到的东西(value, drawable等)。程序会对layouts, anims, animators等逐一调用

  • ResourceTable.cpp的,进行编译,内部流程又可以分为:解析xml文件,赋予属性名称资源id,解析属性值,扁平化为二进制文件。

  • 编译AndroidManifest.xml文,拿到AndroidManifest.xml文件,清空原来的数据,重新解,处理package name重载,把各种相对路径的名字改为绝对路径,编译manifest xml文件,生成最终资源表.9.生成R.java文件

生成我们解压后看到的那个resources.arsc:

2. 处理.aidl文件,生成对应的Java接口文件

  • aidl,全名Android Interface Definition Language,即Android接口定义语言。
    输入:aidl后缀的文件。输出:可用于进程通信的C/S端java代码,位于build/generated/source/aidl。

3. 通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件

我们有了R.java和aidl生成的Java文件,再加上工程的源代码,现在可以使用javac进行正常的java编译生成class文件了。

输入:java source的文件夹(另外还包括了build/generated下的:R.java, aidl生成的java文件,以及BuildConfig.java)。输出:对于gradle编译,可以在build/intermediates/classes里,看到输出的class文件。

源码编译之后,我们可能还会对其进行代码的混淆,混淆的作用是增加反编译的难度,同时也将一些代码的命名进行了缩短,减少代码占用的空间。混淆完成之后,会生成一个混淆前后的映射表,这个是用来在反应我们的应用执行的时候的一些堆栈信息,可以将混淆后的信息转化为我们混淆前实际代码中的内容。

4. 通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex

调用dx.bat将所有的class文件(上一步生成的以及第三方库的)转化为classes.dex文件,dx会将class转换为Dalvik字节码,生成常量池,消除冗余数据等。

5. 通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk

打包生成APK文件。旧的apkbuilder脚本已经废弃,现在都已经通过sdklib.jar的ApkBuilder类进行打包了。输入为我们之前生成的包含resources.arcs的.ap_文件,上一步生成的dex文件,以及其他资源如jni、jar包内的资源。

大致步骤为
以包含resources.arcs的.ap_文件为基础,new一个ApkBuilder,设置debugMode
apkBuilder.addZipFile(f);
apkBuilder.addSourceFolder(f);
apkBuilder.addResourcesFromJar(f);
apkBuilder.addNativeLibraries(nativeFileList);
apkBuilder.sealApk(); // 关闭apk文件
generateDependencyFile(depFile, inputPaths, outputFile.getAbsolutePath());

6. 通过Jarsigner工具,对上面的apk进行debug或release签名

对apk文件进行签名。APK需要签名才能在设备上进行安装很多时候我们在逆向改完后,会因为没有签名文件导致最后的apk无法正常使用,又细分为本地验证和服务器验证。

7. 通过zipalign工具,将签名后的apk进行对齐处理。

调用buildtoolszipalign,对签名后的apk文件进行对齐处理,使apk中所有资源文件距离文件起始偏移为4字节的整数倍,从而在通过内存映射访问apk文件时会更快。同时也减少了在设备上运行时的内存消耗。这样我们的最终apk就生成完毕了。

关于zipalign工具,根据名字就知道是个zip文件对齐的工具。使得apk中的资源文件偏离文件起始位置4个字节,从而可以通过mmap()直接访问,从而减少RAM占用。

参考文档

1、官网 :配置构建
2、apk 构建流程
3、Android打包系列——打包流程梳理
4、APK打包安装过程

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

推荐阅读更多精彩内容