🍵补齐Android技能树——从AGP构建过程到APK打包过程(上)

简介: Android Gradle Plugin,简称 AGP,老早之前就想好好研究下Android APK的打包过程,毕竟 APK包体积优化 的前置知识之一。

0x1、网上流传的三张APK打包流程图


Android官网 有一张新的打包流程图(左),相比起旧的流程图(右)更抽象,隐藏了很多细节:


网络异常,图片无法展示
|


在 Android Studio Project Site 还找到了一张更详细的图:


网络异常,图片无法展示
|


如果只是满足于一个写基础业务的Android开发仔,了解下足矣,不过如果想有更深的造诣,还是建议往下学的。


本节就来了解下AGP的构建过程,以及简单了解下APK的打包过程~


Tips:Tasks那么多,不可能一个个去精读源码解析,不同插件版本还有差异,不如授之以渔,本文的目的就是让读者遇到问题时懂得如何追根溯源,找到对应的源码。


0x2、如何查看插件源码


研究对象是AGP的源码,所以要先搞一份源码,方法有下述几种:


1. 下载完整源码


如果磁盘空间比较充足,可以通过repo的方式,将Android Gradle Plugin的源码下载到本地(貌似30多G):


# 最新源码的只有3.4.0的
repo init -u https://android.googlesource.com/platform/manifest -b gradle_3.4.0
repo sync


2. 下载部分源码


当然不需要编译的话,可以直接下对应源码包,来到下述地址:build-system

点tgz下载:


网络异常,图片无法展示
|


然后用VS Code之类的代码查看工具查看即可~


3. 取巧(推荐)


在app层级的build.gradle添加下述依赖:


implementation 'com.android.tools.build:gradle:3.4.0'


build下,然后在左侧 External Libraries 即可找到源码:


网络异常,图片无法展示
|


0x3、阅读源码前的一些补充


阅读源码前建议温习下我前面写的三篇文章,另外补充点姿势:

Gradle Plugin 中的Task主要有三种:普通Task、增量Task、Transform。

Task一般会继承 DefaultTask 或 IncrementalTask,而 @TaskAction 注解的方法,就是此Task做的事。


继承 IncrementalTask 的类为增量Task,这个增量是相对于全量来说的,全量指的是:调用完clean后第一次编译过程,修改代码或资源后再次编译,就是增量编译。几个关键方法:


public abstract class IncrementalTask extends BaseTask {
    // 是否需要增量,默认false
    @Internal protected boolean isIncremental() { }  
    // 需要子类实现,全量时执行的任务
    protected abstract void doFullTaskAction() throws Exception;
    // 增量时执行的任务,默认什么都不执行,参数是增量时修改过的文件
    protected void doIncrementalTaskAction(Map<File, FileStatus> changedInputs) throws Exception{ }
    @TaskAction
    void taskAction(IncrementalTaskInputs inputs) throws Exception {
        // 判断是否是增量,是执行doIncrementalTaskAction,否则执行doFullTaskAction
    }
    // 获取修改文件
    private Map<File, FileStatus> getChangedInputs(IncrementalTaskInputs inputs) { }
}


至于 Transform(变换),是Android官方提供给开发者,在**.class → .dex转换期间用来修改.class文件的一套API**,留意transform() 方法的实现就好。


0x4、执行gradle assemble的Task链


我们常常使用下面的命令来打包APK:


gradlew assemble


可以由此入手,看下打包一次都涉及到了哪些Task,键入下述命令(linux、mac使用./gradlew):


gradlew assemble --console=plain


输出结果及要点简述如下所示:


:app:preBuild UP-TO-DATE    → 空task,锚点
:app:preDebugBuild  → 空task,锚点
:app:compileDebugAidl NO-SOURCE → 处理AIDL
:app:checkDebugManifest → 检查Manifest是否存在
:app:compileDebugRenderscript NO-SOURCE → 处理renderscript
:app:generateDebugBuildConfig   → 生成 BuildConfig.java
:app:mainApkListPersistenceDebug → 生成 app-list.gson
:app:generateDebugResValues → 生成resvalue,generated.xml
:app:generateDebugResources → 空task,锚点
:app:mergeDebugResources    → 合并资源文件
:app:createDebugCompatibleScreenManifests   → manifest文件中生成compatible-screens,指定屏幕适配
:app:processDebugManifest → 合并manifest.xml文件
:app:processDebugResources → aapt打包资源
:app:compileDebugKotlin → 编译Kotlin文件
:app:prepareLintJar UP-TO-DATE → 拷贝 lint jar包到指定位置
:app:generateDebugSources → 空task,锚点
:app:javaPreCompileDebug → 生成 annotationProcessors.json 文件
:app:compileDebugJavaWithJavac → 编译 java文件
:app:compileDebugNdk → 编译ndk
:app:compileDebugSources → 空task,锚点
:app:mergeDebugShaders → 合并 shader文件
:app:compileDebugShaders → 编译 shaders
:app:generateDebugAssets → 空task,锚点
:app:mergeDebugAssets → 合并 assests文件
:app:validateSigningDebug → 验证签名
:app:signingConfigWriterDebug → 编写SigningConfig信息
:app:checkDebugDuplicateClasses → 检查重复class
:app:transformClassesWithDexBuilderForDebug → class打包成dex
:app:transformDexArchiveWithExternalLibsDexMergerForDebug → 打包第三方库的dex
:app:transformDexArchiveWithDexMergerForDebug → 打包最终的dex
:app:mergeDebugJniLibFolders → 合并jni lib 文件
:app:transformNativeLibsWithMergeJniLibsForDebug → 合并jnilibs
:app:transformNativeLibsWithStripDebugSymbolForDebug → 去掉native lib里的debug符号
:app:processDebugJavaRes NO-SOURCE → 处理java res
:app:transformResourcesWithMergeJavaResForDebug → 合并java res
:app:packageDebug  → 打包apk
:app:assembleDebug → 空task,锚点
:app:extractProguardFiles → 生成混淆文件
# 还会打一个release包,task和上述基本一致,此处省略~


当然,也可以直接在 Build 窗口直接查看,双击右侧Gradle窗口中assemble的Task,然后观察此窗口:


网络异常,图片无法展示
|


啧啧,还可以看到每个Task的执行时间,不错,但先不跟每个Task具体内容,而是跟下AGP的构建过程~


0x5、AGP的构建过程


上一节将Gradle插件时说过,每个插件都会配置一个 id名字.properties 的文件,在此写上插件的实现类,全局搜定位到下述文件:


网络异常,图片无法展示
|


打开:


网络异常,图片无法展示
|


指向:AppPlugin 类,跟下:


网络异常,图片无法展示
|


上节说过:插件类都继承于 Plugin,入口函数 apply(),但在这里没找到,跟下:AbstractAppPlugin → BasePlugin。


① BasePlugin


网络异常,图片无法展示
|


行吧,在BasePlugin中重写了 apply() 方法,里面调用了两个函数,先跟下:basePluginApply()


网络异常,图片无法展示
|


执行一些检查操作,接着是 插件的初始化及配置,而另一个函数:

pluginSpecificApply() 则是空实现,接着跟下:配置项目、配置扩展及创建Tasks的过程。


相关文章
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
368 3
|
存储 API Android开发
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
1107 4
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
|
移动开发 安全 Java
Android历史版本与APK文件结构
通过以上内容,您可以全面了解Android的历史版本及其主要特性,同时掌握APK文件的结构和各部分的作用。这些知识对于理解Android应用的开发和发布过程非常重要,也有助于在实际开发中进行高效的应用管理和优化。希望这些内容对您的学习和工作有所帮助。
1938 83
|
安全 算法 小程序
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
1264 28
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
|
前端开发 Java 编译器
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
756 36
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
797 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
1318 5
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
484 0
|
Java Android开发
安卓apk包反编译
拿到安卓的apk包如何,如何反编译呢。流程如下
1265 0
安卓apk包反编译
Android APK反编译就这么简单 详解(附图)
Android APK反编译就这么简单 详解(附图)
1559 0
Android APK反编译就这么简单 详解(附图)

热门文章

最新文章

  • 1
    为什么微信发送的APP安装不了,.apk转化为.apk.1
    2733
  • 2
    【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
    1264
  • 3
    Android历史版本与APK文件结构
    1938
  • 4
    Cocos2d-x 游戏开发-打包apk被默认自带了很多不必要的权限导致apk被报毒,如何在Cocos 2d-x中强制去掉不必要的权限-优雅草卓伊凡
    434
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    756
  • 6
    【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
    1837
  • 7
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    797
  • 8
    apk安装包EXE,mis程序打包后报毒的正确处理方式-千万不要再人傻钱多被骗-真正的合法途径的处理方式才是正确的-apk安装包EXE,mis程序如何处理-优雅草央千澈
    729
  • 9
    使用Kivy创建“Hello World”应用并打包成APK
    2851
  • 10
    使用keytool查看Android APK签名
    3072