• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Android 完整的apk打包流程

武飞扬头像
大强Dev
帮助188

在Android Studio中,我们需要打一个apk包,可以在Gradle task 任务中选一个 assembleDebug/assembleRelease 任务,

控制台上就可以看到所有的构建相关task:

可以看到,这么多个task任务,执行是有先后顺序的,其实主要就是以下步骤:

//aidl 转换aidl文件为java文件
  > Task :app:compileDebugAidl

//生成BuildConfig文件
  > Task :app:generateDebugBuildConfig

//获取gradle中配置的资源文件
  > Task :app:generateDebugResValues

// merge资源文件
  > Task :app:mergeDebugResources

// merge assets文件
  > Task :app:mergeDebugAssets
  > Task :app:compressDebugAssets

// merge所有的manifest文件
  > Task :app:processDebugManifest

//AAPT 生成R文件
  > Task :app:processDebugResources

//编译kotlin文件
  > Task :app:compileDebugKotlin

//javac 编译java文件
  > Task :app:compileDebugJavaWithJavac

//转换class文件为dex文件
  > Task :app:dexBuilderDebug

//打包成apk并签名
  > Task :app:packageDebug

依靠这些关键步骤最后就能打包出一个apk。

首先看

第一步:aidl(编译aidl文件)

将项目中的aidl文件编译为java文件,AIDL用于进程间通信

第二步:生成BuildConfig文件

在项目中配置了 buildConfigField等信息,会在BuildConfig class类里以静态属性的方式展示:

第三步:合并Resources、assets、manifest、so等资源文件

在我们的项目中会依赖不同的库、组件,也会有多渠道的需求,所以merge这一步操作就是将不同地方的资源文件进行整合。 多个manifest文件也需要整理成一个完整的文件,所以如果有属性冲突这一步就会报错。资源文件也会整理分类到不同的分辨率目录中。

资源处理用的工具是aapt/aapt2

注意AGP3.0.0之后默认通过AAPT2来编译资源,AAPT2支持了增量更新,大大提升了效率。

AAPT 工具负责编译项目中的这些资源文件,所有资源文件会被编译处理,XML 文件(drawable 图片除外)会被编译成二进制文件,所以解压 apk 之后无法直接打开 XML 文件。但是 assets 和 raw 目录下的资源并不会被编译,会被原封不动的打包到 apk 压缩包中。 资源文件编译之后的产物包括两部分:resources.arsc 文件和一个 R.java。前者保存的是一个资源索引表,后者定义了各个资源 ID 常量。这两者结合就可以在代码中找到对应的资源引用。比如如下的 R.java 文件:

实际上被打包到 apk 中的还有一些其他资源,比如 AndroidManifest.xml 清单文件和三方库中使用的动态库 .so 文件。

第四步:编译java文件(用到的工具 javac )

1、java文件包含之前提到的AIDL 生成的java文件

2、java代码部份:通过Java Compiler 编译项目中所有的Java代码,包括R.java.aidl文件生成的.java文件、Java源文件,生成.class文件。在对应的build目录下可以找到相关的代码

3、kotlin代码部份:通过Kotlin Compiler编译项目中的所有Kotlin代码,生成.class文件

注:注解处理器(APT,KAPT)生成代码也是在这个阶段生成的。当注解的生命周期被设置为CLASS的时候,就代表该注解会在编译class文件的时候生效,并且生成java源文件和Class字节码文件。

第五步: Class文件打包成DEX(dx/r8/d8等工具编译class文件)

  • 在原来 dx是最早的转换工具,用于转换class文件为dex文件。
  • Android Studio 3.1之后,引入了D8编译器和 R8 工具。
  • Android Studio 3.4之后,默认开启 R8 具体的区别可以点击看看

注意:JVM 和 Dalvik(ART) 的区别:JVM执行的是.class文件、Dalvik和ART执行的.dex文件。具体的区别可以点击看看

而在编译class文件过程也常用于编译插桩,比如ASM,通过直接操作字节码文件完成代码修改或生成。

第六步:apkbuilder/zipflinger(生成APK包)

这一步就是生成APK文件,将manifest文件、resources文件、dex文件、assets文件等等打包成一个压缩包,也就是apk文件。 在老版本使用的工具是apkbuilder,新版本用的是 zipflinger。 而在AGP3.6.0之后,使用zipflinger作为默认打包工具来构建APK,以提高构建速度。

第七步: zipalign(对齐处理)

对齐是Android apk 很重要的优化,它会使 APK 中的所有未压缩数据(例如图片或原始文件)在 4 字节边界上对齐。这使得CPU读写就会更高效。

也就是使用工具 zipalign 对 apk 中的未压缩资源(图片、视频等)进行对齐操作,让资源按照 4 字节的边界进行对齐。这种思想同 Java 对象内存布局中的对齐空间非常类似,主要是为了加快资源的访问速度。如果每个资源的开始位置都是上一个资源之后的 4n 字节,那么访问下一个资源就不用遍历,直接跳到 4n 字节处判断是不是一个新的资源即可。

第八步: apk 签名

没有签名的apk 无法安装,也无法发布到应用市场。

大家比较熟知的签名工具是JDK提供的jarsigner,而apksignerGoogle专门为Android提供的签名和签证工具。

其区别就在于jarsigner只能进行v1签名,而apksigner可以进行v2v3v4签名。

  • v1签名

v1签名方式主要是利用META-INFO文件夹中的三个文件。

首先,将apk中除了META-INFO文件夹中的所有文件进行进行摘要写到 META-INFO/MANIFEST.MF;然后计算MANIFEST.MF文件的摘要写到CERT.SF;最后计算CERT.SF的摘要,使用私钥计算签名,将签名和开发者证书写到CERT.RSA。

所以META-INFO文件夹中这三个文件就能保证apk不会被修改。

  • v2签名

Android7.0之后,推出了v2签名,为了解决v1签名速度慢以及签名不完整的问题。

apk本质上是一个压缩包,而压缩包文件格式一般分为三块:

文件数据区,中央目录结果,中央目录结束节。

而v2要做的就是,在文件中插入一个APK签名分块,位于中央目录部分之前,如下图:

这样处理之后,文件就完成无法修改了。

  • v3签名

Android 9 推出了v3签名方案,和v2签名方式基本相同,不同的是在v3签名分块中添加了有关受支持的sdk版本和新旧签名信息,可以用作签名替换升级。

  • v4签名

Android 11 推出了v4签名方案。

最后,apk得以完成打包

PMS 在安装过程中会检查 apk 中的签名证书的合法性,具体安装apk内容稍后介绍。

apk内容包含如下:

总体的打包流程图如下:

,,

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanffaaj
系列文章
更多 icon
同类精品
更多 icon
继续加载