谈谈打包之整体介绍

本文探讨了打包在IT开发中的重要性,特别是在移动开发中的应用,如Android的APK构建。文章详细介绍了打包的定义、生活中的打包场景,以及Android打包流程,包括Gradle工具的作用,从初始化、配置到执行的完整过程。
摘要由CSDN通过智能技术生成

不管你是做移动开发、前端开发还是后端开发,一定会遇到一个概念——打包,那打包是什么?为什么要打包?以及如何打包呢?

打包是什么,为什么要打包

在我们日常生活中有哪些常见的打包场景呢?旅行打包、快递打包、礼品打包、资料文档打包,这些打包是指把若干物品在空间上有机的组合在一起,对外呈现为一个整体的过程打包的目的是为了更方便、安全地储存、运输、呈现和使用物品
在技术领域依旧如此,打包一般指将程序的源代码、资源文件和依赖库等整合成一个整体的过程,打包是为了程序能够更加方便、安全的使用(包括存储、传输、复制、部署、安装、运行等)。

如何打包

马上过年了,X厂要发放新年大礼包给员工,那制作过程大概是这样的:确定大礼包物品清单以及包装盒样式→确定每个物品摆放位置和顺序→按顺序对物品进行摆放→封包→打上防伪标签,在这个打包过程中,其实还隐藏着另一个流程,那就是每个步骤所需要的环境和工具的准备。在技术领域,打包过程亦是如此,接下来就Android打包过程具体展开:

Android 打包流程

打包在Android上也叫APK构建,打包就是把**Android工程源码变为APK的过程,使用的工具叫Gradle。**首先我们得有个认知,每个APK构建的大流程是确定的,只是不同的APP依赖三方库(物品清单一部分)、签名(防伪手段)、使用工具集、打包后存放位置一些自定的地方不同,我们才需要进行对打包控制文件(build.gradle)进行配置。**我们觉得打包流程不容易理解是因为我们能够操作的build.gradle等文件都只是配置文件,打包的内部逻辑和流程是对我们隐藏的。**打包跟其他任何工作一样都是分为三步走:
确定工作内容和范围→确定工作分工和顺序→顺序执行每个任务,分别对应上述流程,Android打包也分为三个大的步骤:

  • 初始化(Initialization)
  • 配置(Configuration)
  • 执行(Execution)

我们在setting和build.gradle的配置也是在初始化和配置阶段生效的。下面我们逐个进行介绍

一 、初始化 Initialization

  1. 从工程源码根目录开始查找setting.gradle文件;
  2. 根据setting.gradle文件中的配置来决定哪些模块参与构建;
  3. 首先为根build.gradle生成一个Project实例,接下来为每一个setting.gradle中配置的模块(对应build.gradle)生成一个Project实例,根build.gradle对应的Project是其他build.gradle对应Project的父Project;

注意:
① 因为每个build.gradle 都对应一个Project对象,Project对象类似于Android中的 Context,在build.gradle中获取gradle系统方法都是通过内置的project对象或者 getProject() 得到上下文后去获取。
② 这个阶段我们配置的task、回调都不会被执行,可以认为是Android中的类加载到内存和实例对象初始化阶段。

二、配置 Configuration

1. 对每个build.gradle对应的Project进行配置,所谓的配置主要是指 ① 下载并初始化插件 ②配置 Android 的编译版本、签名、产品风味等 ③ 下载依赖库 ④注册自定义Task 等,其实这四个主要事情也是一个build.gradle中所有的内容。project配置和执行都是采用广度优先遍历,那就是父project先执行,然后是按照Setting.gradle中顺序执行子project, 这个阶段也叫 Project Evaluation
2. 执行Project evaluation的回调,比如Project.beforeEvalution 、Project.afterEvalution等;
3. 广度优先顺序为每个Project注册task,执行task create回调(如果有),示例如下:

tasks.whenTaskAdded { task ->
    println("hahaha task added call back name= "+task.name)
}

4. 为每一个Task创建一个依赖图,依赖图就是来说明运行这个task要先执行哪些Task的图;
5. 当所有Task的依赖图构建完毕,发送 task构建图完成通知。如果用户定义了回调就可以收到

project.gradle.taskGraph.addTaskExecutionGraphListener(new TaskExecutionGraphListener() {
    @Override
    void graphPopulated(TaskExecutionGraph graph) {
        println("hahaha task TaskExecutionGraph call back")
    }
})

**小结:配置就是决定打包的具体内容、使用工具和详细流程。**我们大部分在build.gradle中自定义的东西都是在配置阶段生效和执行。

注意:

  • 我们在Android studio执行sync的时候其实就是执行了初始化+配置,我们配置了更多的东西比如更多三方库,更多构建变体 这个sync时间就会更长;
  • 执行任何Task都要重新执行整个项目的初始化和配置阶段,但是如果之前执行过sync或者这两个步骤,而且所有的buid.gradle都未变化,gradle内部会找到之前的缓存并跳过一个个任务的执行。

三、执行:Execution

其实前面两个阶段都是读入决策和准备阶段,真正做事都是在这个阶段——打包(也叫构建、assemble),根据不同的构建类型和产品风味会有多个打包产物,接下来我们就指对最常见的assembleRelease进行展开。  
本文前面讲所谓**打包就是把Android App源码变为APK的过程**,Android App工程源码是什么,结构是怎么样的,做Android开发的应该都比较清晰,主要有AndroidManifest配置文件、java代码、kotlin代码、XML、图片、依赖库地址、本地库(jar、aar、so)等,这里就展开介绍;**而APK其实就是一个**包含编译后的代码和资源的**压缩文件**,我们找到一个APK(改后缀为.zip)解压得到文件列表如下:  

重点模块介绍如下:
1、META-INF
META是Meta Data的缩写,元数据是描述数据的数据,APK是一个压缩包,可以认为是一种数据结构,那它的Meta-data就是描述这个APK相关信息的数据,比如使用三方库版本号、JAR包签名(V1签名文件,V2签名等会是签名在包装APK之上,打开后就破坏了这个签名)等。
2、res
res目录下包含了整个APP工程的资源,就是说打包时候会把一个APP所有模块,依赖库中的资源挑选出来,进行合并 、缩减(比如开启R8优化,工程种没有使用的资源就不会打包到APK),重命名等操作,最后整理出来一份资源放这里,它对应着我们工程目录中的资源目录:

3、AndroidManifest.xml
**AndroidManifest.xml包含了整个APP所有模块的配置文件,**就是说打包时候会把一个APP所有模块、依赖库中的AndroidManifest文件拿出来合并、优化得到这一份总的AndroidManifest配置文件。
4、classes.dex
classes.dex 文件是 对应Android 工程中的Java和Kotlin源码,是他们经过编译后生成的 Android虚拟机(Dalvik、ART) Executable(可执行) 文件,.dex 后缀就是 Dalvik Excecutable的缩写。
5、resources.arsc
resources.arsc是所有模块的资源地址映射表合集, 就是说我们在代码中寻找资源是 R.id.XX,但是实际读一个文件是需要文件路径的,这个文件就是把Id映射为路径的表。
6、assets
assets目录就是我们原来放在各个模块assets目录下的so、图片、apk等文件的合集,这部分是直接移动复制过来,没有优化、没有压缩,所以搞包体积优化这地方是重点。
7、lib目录
lib目录存储了整个工程的所有so文件,这些so文件来源于本模块、依赖模块、依赖库等地方,如果能够确定每个渠道包对应的设备使用CPU架构,可以在Android默配置、flavor 中配置, 配置后就只打包需要的SO文件,使用这个配置能有效减少APK包体积大小如下图:

接下来就谈谈这些产物是如何生成的,Android官方给出的App打包详细流转图如下:

注意:

  • 这些流程是配置阶段决定好的,执行阶段就是按找之前决定的进行执行;
  • 只要没有先后顺序的任务都是可以并行执行的,Gradle也是多线程工作的;

名词解释
AAPT
aapt 是Android Asset Packaging Tool的缩写,是编译和打包资源的工具,在SDK的build-tools目录下。

ApkBuilder
ApkBuilder 相当于一个压缩工具,它可以将已经编译好的 Java 代码、资源文件、AndroidManifest.xml等打包成一个 ZIP 文件,即 APK 文件

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题
图片

  • 30
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值