美文网首页
Android 打包之 Gradle

Android 打包之 Gradle

作者: 斋芳女 | 来源:发表于2023-08-07 14:51 被阅读0次

    一、什么是Gradle

    Gradle 是目前非常流行的一个项目构建工具,它不局限于前端或者后端,利用基于jvm的动态语言Groovy,语法灵活,配置简单,方便扩展。

    Tips:Gradle是Gradle,AndroidGradle是AndroidGradle,不能混为一谈,可以理解Google为了在AS上使用Gradle来构建Project,自己根据Android项目拓展了Gradle,开发出了AndroidGradle插件,结合了AndroidTools等工具,方便对Android项目进行构建。

    详解:https://www.cwiki.us/display/GradleZH/What+is+Gradle

    二、Android中的Gradle

    Android中的Gradle可以称为gradle插件,要想编译安卓项目,不仅要下载gradle,也要下载Android对应的gradle插件,插件中包含了Gradle和Android一些工具的结合,目的是为了构建Android Project。

    贴一张Gradle插件版本号和Gralde版本的对应版本

    https://developer.android.google.cn/studio/releases/gradle-plugin

    gradle/wrapper/gradle-wrapper.properties 中配置gradle版本,build文件中配置gradle插件版本

    classpath 'com.android.tools.build:gradle:3.3.2' ----插件版本

    distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip ---- gradle版本


    1.Android-sync project with gradle file发生了什么?

    详解来自:https://developer.android.com/studio/build/dependencies?hl=zh-cn

    首先,看一下安卓整个项目结构:

    挨个说:

    顶层build.gradle文件:

    顶层 build.gradle 文件位于项目的根目录下,用于定义适用于项目中所有模块的依赖项。默认情况下,顶层 build 文件使用 plugins 代码块定义项目中所有模块共用的 Gradle 依赖项。此外,顶层 build 文件还包含用于清理 build 目录的代码。以下代码示例说明了创建新项目后可在顶层 build.gradle 文件中找到的默认设置和 DSL 元素。

    其中配置项解析:

    project/build.gradle project/build.gradle

    settings.gradle文件:

    主要功能:配置要构建几个模块

    settings.gradle

    模块的gradle文件配置,module/build.gradle

    module/build.gradle module/build.gradle

    小点补充:

    Gradle编译后,只会停留到加载各种依赖资源和初步编译代码阶段

    常见闭包参数详解:

    android DSL

    –领域特定语言(domain-specific languages,简称DSL)

    defaultConfig{}默认配置,是ProductFlavor类型。它共享给其他ProductFlavor使用

    sourceSets{ }源文件目录设置,是AndroidSourceSet类型。

    buildTypes{ } BuildType类型

    signingConfigs{ }签名配置,SigningConfig类型

    productFlavors{ }产品风格配置,ProductFlavor类型

    testOptions{ }测试配置,TestOptions类型

    aaptOptions{ } aapt配置,AaptOptions类型

    lintOptions{ } lint配置,LintOptions类型

    dexOptions{ } dex配置,DexOptions类型

    compileOptions{ }编译配置,CompileOptions类型

    packagingOptions{ } PackagingOptions类型

    jacoco{ } JacocoExtension类型。用于设定jacoco版本

    splits{ } Splits类型。

    android{… }配置了用于android构建的所有参数。这是Android DSL的入口。

    2.那么,打包过程是怎样的?

    内容整理来自:https://docs.gradle.org/current/userguide/build_lifecycle.html

    首先gradle构建生命周期:

    初始化阶段(Initialization)

    配置阶段(Configuration)

    执行阶段(Execution)

    初始化阶段:

    Gradle支持单工程或者多工程构建,初始化阶段的任务是确定有多少工程需要构建,创建整个项目的层次结构,并且为每一个项目创建一个Project实例对象。

    如果是多工程构建,一般都会在根工程目录下声明一个settings.gradle脚本,在脚本中include所有需要参与构建的子工程,通过解析settings.gradle脚本,读取include信息,确定有多少个Project需要构建。

    配置阶段:

    配置阶段的主要任务是生成整个构建过程的有向无环图

    确定了所有需要参与构建的工程后,通过读取解析各个工程对应的build.gradle脚本,构造Task任务,并根据Task的依赖关系,生成一个基于Task的有向无环图TaskExecutionGraph

    执行阶段:

    通过读取配置阶段生成有向无环图TaskExecutionGraph,按顺序依此执行各个Task,像流水线一样,一步一步构建整个工程,这也是构建过程中最耗时的阶段。

    图片来自网络

    ///项目中具体log图片待补充

    3.接着,主要task有哪些?

    先贴一张打包大致流程图,图片来自网络:

    图片来自网络

    aapt-打包res资源文件,生成R.java、resources.arsc和res文件(二进制&非二进制如res/raw和pic保持原样)

    AIDL-Android借口定义语言,Android提供的IPC(Inter Process Communication,进程间通信)的一种独特实现。这个阶段处理.aidl文件,生成对应的Java接口文件。

    Java Compiler-通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件。

    dex-通过dex命令,将.class文件和第三方库中的.class文件处理生成class.dex。

    apkbuilder-将class.dex、resources.arsc、res文件夹(res/raw资源被原封不动的打包进APK之外,其他资源都会被编译或者处理)、OtherResouces(assets文件夹)、AndroidManifest.xml打包进apk文件。

    Jarsigner-对上面的apk进行debug或release签名

    aipalign-将签名后的pak进行对其处理

    图片来自网络

    Task序列:

    1.1

    分段来说:

    1.2

    1-4: 

    preDebugBuild task主要是得到compile 和 runtime的依赖包并对其做一些版本号,依赖等的校验工作。compileDebugAidl,处理记录aidl和java相关的信息。generateDebugBuildConfig 生成BuildConfig文件

    1.3

    这一部分task主要作用是整理资源合并,分辨率资源文件整理等

    其中generateDebugResValues比较重要,它的作用是,配置在gradle中的一些参数,自动整理到res目录中供代码调用,比如:

    1.4

    如果你有该配置的话,执行./gradlew generateDebugResValues

    则会生成以下代码:

    1.5

    可以方便的在代码中调用

    1.6

    这一部分task主要任务是一些加jar文件以及载处理依赖关系。其中

    compileDebugJavaWithJavac尤为重要:

    ./gradlew compileDebugJavaWithJavac

    一共做了比较重要的几件事:

    已知内容(依赖此task之前task)

    依赖工程的jar文件

    javaPreCompileDebug 任务的输出json文件

    项目的java文件

    项目生成的R文件,buildconfig文件,aidl等一系列重要文件

    做一下输出:

    annotationProcessor 生成的java文件

    生成的classes文件

    下面是transform

    1.7

    transform vs task

    TransformManager.java

    1.8

    addTransform 方法在执行过程中,会将 Transform 包装成一个 AndroidTask 对象,所以transfrom最终会被转换成一个task

    ./gradlew transformClassesWithDexBuilderForDebug

    根据依赖库的jar文件和class文件,生成dex文件。

    值得注意的是,既然是生成dex文件,但是为甚么输出后有后缀为jar文件,实际情况是,jar后缀文件解压后,是dex。了解一下就行。

    1.9

    最后就是打包签名输出apk

    4.所以我们利用task可以做些什么?

    Task一些关键字语法:

    http://doc.yonyoucloud.com/doc/wiki/project/GradleUserGuide-Wiki/more_about_tasks/README.html

    首先,命令行 gradle task --all 可以看到项目中所有的task

    那么我们如何方便看到task之间的依赖关系呢,这里有个插件 task-tree可以辅助我们打印task之间的关系

    还有一个 gradle-visteg有兴趣的小伙伴可以看看。

    首先纠正一个配置阶段对task的定义的理解:

    1.10

    在配置阶段,会输出那些内容呢?

    事实上,会输出,hello,helloworld的内容,那么问题来了,不是不会执行task吗?为什么会输出呢?

    这个跟方法块理解不一样,配置阶段是会走一遍task的配置,但是执行是从doFirst开始的,只有在执行task的时候,才会从doFirst入口开始执行。doLast结束。

    不论执行什么task,都会完成一遍配置,哪怕clean一下缓存。

    afterEvaluate

    x0;这个关键字是指配置阶段结束后,之所以所有hook内容放在该关键字处,是因为只有在这里才能拿到所有task的信息,然后进行操作。

    1.11

    gradle.taskGraph.whenReady

    x0;这里输出的是当前任务构建需要依赖的所有的task的集合

    1.12

    所以,在配置阶段结束后,我们可以做任何想做的操作,插入自己的task

    列举几个项目中的例子:图片待补充。。。

    文章中诸多内容借鉴了其他文章,犹豫时间久远未记录原文档地址,希望我们每个技术人都可以向原创致敬。谢谢观看。

    相关文章

      网友评论

          本文标题:Android 打包之 Gradle

          本文链接:https://www.haomeiwen.com/subject/nskovrtx.html