APK 是怎么来的?- Android 构建流程解析

news2024/11/25 14:19:54

一、 APK 组成解析


在开始解析 Android 构建流程之前,我们先来看下构建的最终产物 APK 的整体组成 img

APK 主要由五个部分组成,分别是: Dex:.class 文件处理后的产物,Android 系统的可执行文件 Resource:资源文件,主要包括 layout、drawable、animator,通过 R.XXX.id 引用 Assets:资源文件,通过 AssetManager 进行加载 Library:so 库存放目录 META-INF:APK 签名有关的信息

1.1 Apk 分析工具

工欲善其事,必先利其器,既然想分析 APK 必然少不了好用的工具

① Android Studio 自带的 APK 分析器

通过 APK 分析器,我们可以完成这些操作 1、查看 APK 中文件(如 DEX 和 Android 资源文件)的绝对大小和相对大小 2、了解 DEX 文件的组成 3、快速查看 APK 中文件(如 AndroidManifest.xml)的最终版本 4、对两个 APK 进行并排比较 img img

② ClassyShark

ClassyShark 可以作为 AS 自带 APK 分析器的补充,帮我们分析 dex 中的详细数据,以及查看 APK 中的总方法数以及各个模块的方法数分布。 img img

1.2 Dex 知识点拓展

当我们在 Android 查看一个 APK 的时候,可以看到右上角有 Defined Methods 和 Referenced Methods,但大多数人可能不知道这两者的区别,这里简单说明下:

Defined Methods:在这个 Dex 中定义的方法 Referenced Methods:Defined Methods 以及 Defined Methods 引用到的方法 img

Android 有 64K 引用限制,当 type_ids、method_ids 或者 field_ids 超过 65536(64 * 1024)的时候,需要进行 dex 分包,为了 Dex 的数量尽可能少,我们需要尽量实现「Dex 信息有效率」的提升

Dex 信息有效率 = Defined Methods 数量 / Referenced Methods 数量
复制代码

img

二、 构建源码导读


当我们用 Android Studio 进行安装包构建的时候,会发现其实是运行了一连串的 Task,也就是说其实是这些 task 的配合,最终构建出我们的 APK 的。

img

2.1 源码引入

如果我们想更了解 Android 的构建流程,对于相关的源码肯定是要有所了解的。那我们如何看到这些 Task 相关的源码呢,我们知道 Android 是用 Gradle 进行构建的,也就意味着这些 task 其实都是放在 Gradle 中,我们想看 Gradle 中源码的话,可以在 build.gradle 将 Gradle 进行编译。

compileOnly "com.android.tools.build:gradle:3.0.1"
复制代码

编译完之后,可以在 ApplicationTaskManager#createTasksForVariantScope 中找到创建这些 Task 相关的代码,也就意味着顺藤摸瓜找到这些 Task 的真正实现逻辑。

2.2 BuildConfig Task 详解

这里以 BuildConfig 文件的生成为例,来梳理下如何查看某个 task 的代码逻辑。 img

生成 BuildConfig 文件,是通过 ApplicationTaskManager 中通过 createBuildConfigTask 来创建对应的 task。

imgimg

顺着代码逻辑,我们找到最终真正实现这个逻辑的是:GenerateBuildConfig 这个 task,GenerateBuildConfig 是继承自 BaseTask,这里有个小技巧是,Task 中真正的执行逻辑都是在带着 @TaskAction 注解的方法上的,所以我们能很快找到对应的 generate() 方法。可以看到生成 BuildConfig 整体的逻辑还是比较简单的,其实就是将 build.gradle 中自带的属性以及我们自定义的属性进行读取,然后通过 JavaWriter 生成对应的 BuildConfig 文件。 img img

2.3 获取所有 task 对应的类名

看到上面的例子,可能有些人会抛出一个疑问就是那我们怎么确定构建中执行的 task 具体对应哪个类呢,这里提供一个小技巧,其实我们可以在 taskGraph 构建完成之后,将所有 task name 以及对应的 class 进行打印。例如在 build.gradle 中加入这个代码之后,我们在运行的时候,就会把 task 所对应的类名也都一起打印出来。

imgimg

三、构建流程梳理


img

可以看到 Android 构建中会涉及到多个工具,我们可以通过 open $ANDROID_HOME/build-tools 来查看相关的构建工具

img

四、手动构建 APK


最后我们通过命令行来手动打包一个可执行的 APK,能让我们对 APK 构建的理解更加深入。首先需要准备下 代码、资源文件、AndroidManifest 这些构建 APK 的必要文件

img

① 通过 aapt2 compile 将 res 资源编译成 .flat 的二进制文件

aapt2 compile -o build/res.zip --dir res

② 通过 aapt2 link 将 .flat 和 AndroidManifest 进行连接,转化成不包含 dex 的 apk 和 R.java

aapt2 link build/res.zip -I $ANDROID_HOME/platforms/android-30/android.jar --java build --manifest AndroidManifest.xml -o build/app-debug.apk

③ 通过 javac 将 Java 文件编译成 .class 文件

javac -d build -cp $ANDROID_HOME/platforms/android-30/android.jar com/**/**/**/*.java

④ 通过 d8 将 .class 文件转化成 dex 文件

d8 --output build/ --lib $ANDROID_HOME/platforms/android-30/android.jar build/com/tencent/hockeyli/androidbuild/*.class

⑤ 合并 dex ⽂件和资源⽂件

zip -j build/app-debug.apk build/classes.dex

⑥ 对 apk 通过 apksigner 进行签名

apksigner sign -ks ~/.android/debug.keystore build/appdebug.apk

推荐

apk加固与多渠道打包线上优化https://www.bilibili.com/video/BV1uQ4y1U7kq

APK的加固反编译实战https://www.bilibili.com/video/BV1Sv411T7yT

Android 性能调优系列https://0a.fit/dNHYY

Android 车载学习指南https://0a.fit/jdVoy

Android Framework核心知识点笔记https://0a.fit/acnLL

Android 音视频学习笔记https://0a.fit/BzPVh

Jetpack全家桶(含Compose)https://0a.fit/GQJSl

Kotlin 入门到精进https://0a.fit/kdfWR

Flutter 基础到进阶实战https://0a.fit/xvcHV

Android 八大知识体系https://0a.fit/mieWJ

Android 中高级面试题锦https://0a.fit/YXwVq

后续如有新知识点,将会持续更新,尽请期待……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/52329.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android S(31) APP 页面绘制流程

接上一篇app 启动流程调用OnCreate方法,页面布局绘制进入setContentView 1、加载布局setContentView() 这里getWindow()直接返回mWindow,这个早在onCreate 调用前Activity#attach里面完成初始化。 进入attach方法,构建一个窗体对象PhoneWind…

[附源码]SSM计算机毕业设计疫情防控下高校教职工健康信息管理系统JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Docker Cgroups资源控制

目录 一、cgroups简介 cgroups有四大功能: 二、cpu时间片的概念 三、对CPU使用的限制 1 设置CPU使用率上限 (1)查看容器的默认CPU使用限制 2 设置CPU资源占用比(设置多个容器时才有效) 1)创建两个容器…

回归商业初心,宝尊电商“深耕广拓”缔造品牌电商有质增长

今年来,受疫情、通胀、能源等因素影响,全球市场都经历了不同程度的“震荡”。 寒气传递之间,电商行业开始摸索后疫情时代的前进之路。随着财报季来临,市场开始期待从各赛道标杆企业财报中看出行业走势。 11月29日,“…

python3基础语法

Python 常用文件扩展名为 .py,可以新建一个 hello.py 文件开始下面的学习,执行使用命令 python3 hello.py 一、标识符 第一个字母必须是 字母 或 下划线 _标识符的其他的部分由 字母、数字 和 下划线 组成标识符对 大小写敏感 二、保留字&#xff08…

[2022世界杯] 小白也可以看懂的世界杯

⚽文化世界杯 如果问你全球最火,影响力最大的体育赛事是什么?那么很多人会说 “奥运会”!当然不完全对,如果从关注度来说 世界杯的影响力更大! 世界杯与奥运会的不同在于:会员协会的数量,拥有209个会员协会…

【踩坑】double和BigDecimal的精度问题

【踩坑】double和bigdecimal的精度问题背景debug尝试测试代码结果总结背景 今天生产报了个问题,在申报和预算相同的金额的时候,后台返回超出预算。一开始以为是判断逻辑的问题,找了个数据试了下发现重现不出来。又是改数据又是找前端传参最后…

Pose for Everything: Towards Category-Agnostic Pose Estimation 阅读笔记

类无关姿态估计 ECCV 2022 Oral 论文链接 代码链接 其他参考 引入了一个新任务:CategoryAgnostic Pose Estimation (CAPE) 类无关姿态估计 摘要: 目前的2D姿态估计与类别耦合,例如人、动物、车辆。但很多场景需要检测未知类的姿态/关键点。…

我是如何从测试开发做到年薪50万的?

入行测开,马上就要5年了。创业公司待过,大公司也待过,工作这一路走来,一些心得,转变,职场体会,早就想写出来分享一下。这个历程包含了技术的提升,工程师的素养和对这个行业的点滴感悟…

操作系统学习笔记(Ⅳ):文件

目录 1 文件管理 1.1 初识文件管理 1.文件属性 2.文件数据组织 3.向上功能 1.2 文件逻辑结构 1.无结构文件 2.有结构文件 3.顺序文件 4.索引文件 5.索引顺序文件 1.3 文件目录 1.文件控制块 2.目录结构 3.索引结点 1.4 文件物理结构 1.连续分配 2.链接分配 …

【面试题】【ES6】let和const命令 (面试必看)

给大家推荐一个实用面试题库 1、前端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 1、let命令 基本用法 用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。 let…

全国计算机三级嵌入式 - 题库 - 真题(含答案) - 未来教育 - 视频讲解 - 资料获取

全国全国计算机三级嵌入式等级考试 1. 考题大纲 历年不一样。但是换汤不换药。 2. 考试真题 历年全部考题、真题。包含全部答案。 3. 未来教育 考点、知识点、历年真题视频讲解。 4. 资料获取 在本人的博客上传资源里!!!下载不易&#xff0…

[附源码]计算机毕业设计springboot勤工俭学管理小程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

论文投稿指南——中文核心期刊推荐(计算机技术)

>>>深度学习Tricks&#xff0c;第一时间送达<<< &#x1f680; 写在前面 &#x1f431;‍&#x1f3cd; 本期开始&#xff0c;小海带会定期推荐各专业领域的中文核心期刊及论文投稿网址&#xff0c;供大家交流参考 ~ 《中文核心期刊要目总览》——是学术界…

功率放大器主要性能指标是什么(功率放大器工作状态的分类)

电子仪器中&#xff0c;放大器末级都要带动一定的负载&#xff0c;所以末级电路不仅要求可以输出较大幅度电压&#xff0c;而且要求输出较大幅度电流&#xff0c;也就是要求放大器能够对负载输出较大的功率&#xff0c;这种测试仪器就被称为功率放大器。 功率放大器主要性能指标…

人脸检测-级联卷积

人脸检测有好多种cv都有自带 说到人脸检测&#xff0c;应该是近几年不老的话题了&#xff0c;如果要将这技术真的落实到现在产品&#xff0c;其实还有很长的路&#xff0c;不知道大家有没有发现&#xff0c;很多无人超市开始走下坡路&#xff0c;也许不仅仅是技术的原因之一吧…

idea中LeetCode无法正常使用

在风诡云谲的互联网职场中&#xff0c;随时准备好简历和刷题能力是非常必要的&#xff01;在工作时间“光明正大”刷题的神器——LeetCode插件&#xff01; 原来&#xff1a;idea 2019&#xff1b;LeetCode 6.8 目前&#xff1a;idea 2020.3&#xff1b;LeetCode 8.4 一 ide…

ARM-A架构入门基础(四)Cache

14天学习训练营导师课程&#xff1a;周贺贺《ARMv8/ARMv9架构-快速入门》 1. 定义 Cache是ARM中一块可高速访问的内存块&#xff0c;每块cache包含&#xff1a; 主要的内存地址信息&#xff1b;缓存数据。 2. Cache模型 速度方面&#xff1a;L1 cache > L2 cache > L…

从json中获取嵌套对象值(Oracle中的json_value和MySQL中的JSON_EXTRACT) 以及Oracle和MySQL处理日期语法的不同

从json中获取嵌套对象值&#xff08;Oracle中的json_value和MySQL中的JSON_EXTRACT&#xff09; 以及Oracle和MySQL处理日期语法的不同1. 从json中获取嵌套对象值1.1 Oracle 的 json_value1.2 MySQL 的 JSON_EXTRACT2. 日期问题2.1 MySQL2.1.1 获取指定日期2.1.1.1 DATE_SUB() …