我们平时在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

其中:

res中图片和raw文件下内容保持原样,res中其他xml文件内容均转化为二进制形式;assets文件内容保持原样

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占用。

参考文档

java做app流程图,Android App 构建流程分析相关推荐

  1. java制作安卓客户端,java做服务器,android干客户端,实现数据传输

    java做服务器,android做客户端,实现数据传输 许久未动笔,有个小项目开始动工. 需要用一台windows电脑做服务器,在android端与其进行数据交换,实现一些业务. 简单起见,用java ...

  2. Android SDCard UnMounted 流程分析(三)

    前篇地址 Android SDCard UnMounted 流程分析(一) Android SDCard UnMounted 流程分析(二) 前一篇讲到SDCard unmout onEvent 发送 ...

  3. Android -- Wifi启动流程分析

    Android -- Wifi启动流程分析 Android网络各个模式中,Wifi应该是目前最常用的一种网络方式了:下面就简单介绍下Android中Wifi的启动流程. 当我在Setting菜单里点击 ...

  4. 【SemiDrive源码分析】【X9芯片启动流程】27 - AP1 Android Preloader启动流程分析(加载atf、tos、bootloader镜像后进入BL31环境)

    [SemiDrive源码分析][X9芯片启动流程]27 - AP1 Android Preloader启动流程分析(加载atf.tos.bootloader镜像后进入BL31环境) 一.Android ...

  5. android camera2 API流程分析

    Android camera2 API流程分析 Android5.0之后,新推出来了一个类,android.hardware.camera2,与原来的camera的类实现照相和拍视频的流程有所不同,原 ...

  6. Android UI绘制流程分析(三)measure

    源码版本Android 6.0 请参阅:http://androidxref.com/6.0.1_r10 本文目的是分析从Activity启动到走完绘制流程并显示在界面上的过程,在源码展示阶段为了使跟 ...

  7. Google原生输入法LatinIME词库构建流程分析(三)--N-gram信息构建

    N-gram信息的构建在ngram.cpp中进行构建: bool NGram::build_unigram(LemmaEntry *lemma_arr, size_t lemma_num,LemmaI ...

  8. Google原生输入法LatinIME词库构建流程分析(二)

    在Google原生输入法LatinIME词库构建流程分析(一) 中分析LatinIME构建流程进行到了dict_trie->dict_list_->init_list这一步,然后就是构建N ...

  9. 个人开发者做一款Android App需要知道的事情

    在大学时, 自己是学计算机专业的,而且还和老师一起做过一年半的项目. 有时候是不是有这样的想法,做一个自己的网站.但一直未付诸行动. 2012年时, 终于付诸行动了,花了三个月,现学现卖, 熬夜通宵用 ...

最新文章

  1. 双11大考 POLARDB分钟级弹性让企业轻松扩展
  2. VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNTION(翻译)
  3. Oracle 10.2.0.4 高负载 触发 ORA-00494 错误
  4. 华为手机鸿蒙系统官方下载入口,华为鸿蒙系统官方版-华为鸿蒙操作系统官方内侧入口 v1.0.0预约_手机乐园...
  5. c#调用外部dll详解
  6. HDU 2376 Average distance
  7. Dubbo的负载均衡、集群容错、服务降级等机制详解
  8. 冲动是魔鬼!国庆换机如何不花冤枉钱?
  9. java 子类 同名参数_Java -- 父类和子类拥有同名变量
  10. 谷歌Android flash,取消支持Flash 谷歌TV升级安卓4.2.2
  11. 携程酒店数据爬取(新)
  12. 数仓建模—表设计规范
  13. Nodemailer 使用Gmail发送邮件
  14. python使用selenium爬取dell官网驱动(一):获取遍历各驱动的下载网址
  15. Oracle锁机制深度分析
  16. 快速获取iOS APP中的所有素材
  17. 2022年模式识别高峰论坛学习与个人感悟
  18. 使用Vmware workstation出现权限不足
  19. ARM Linux中断机制分析
  20. rospkg.common.ResourceNotFound: ×××××报错

热门文章

  1. 计算机组成-硬件结构-系统总线:知识点汇总、思维导图、流程图、复习笔记
  2. 解决127.0.0.1已拒接连接/ping localhost解析为::1的问题
  3. Mac上Pycharm激活
  4. 苹果手机变成耳机模式怎么调回来_苹果耳机推出“新功能”:打僵尸!
  5. 解决上传图片自动旋转的问题以及对图片进行压缩上传
  6. 学习CNN-1 基础知识
  7. 排队打饭的时间足够带你入门MySQL
  8. 微信也可以发闪照了闪照制作生成微信小程序源码下载,自定义闪照时间支持流量主
  9. 快递100参数错误-面单类错误(电子面单/发货单/模板)常见问题和解决方法
  10. 用计算机弹音乐忘川彼岸倾宸红妆,一句心情说说唯美句子