Gradle 在 Android 中的应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/recordGrowth/article/details/85701450

Gradle 是什么

Gradle 是 Android 项目的默认构建系统,它以领域特定语言 (DSL) —— Groovy 语言描述和操作构建逻辑

Groovy 是一种适用于 Java 虚拟机 (JVM) 的动态语言,它的语法和Java非常相似,并且完全兼容Java

Android APK 的构建流程如下所示,Gradle 就是帮助我们自动实现这一流程的工具
Sbingo

需要注意的是,Gradle 是一个通用的构建工具。它不限于构建 Android 项目,它本身不知道如何构建 Android 项目

想要使用 Gradle 构建 Android 项目就需要:Android Gradle 插件

Android Gradle plugin

Android Gradle plugin 是什么?引用 Android 官网的话:

The Android Studio build system is based on Gradle, and the Android Gradle plugin adds several features that are specific to building Android apps.

就是说 Android Gradle 插件提供了专门用于构建 Android apps 的功能

可以进一步理解为:是这个插件使用了 Gradle 来构建 Android apps

Gradle 在不断更新,为了使用一些新版本的特性,插件的版本也需要随之更新

下面是目前最新的 Android Gradle 插件 和 Gradle 之间的版本对应关系

扫描二维码关注公众号,回复: 6393834 查看本文章

在这里插入图片描述
Android 项目中这两个版本号需要遵守上面这个表格,否则构建时可能会报错

Gradlew 是什么

Gradlew 是 Gradle Wrapper 的缩写,Wrapper是对Gradle的一层包装

Gradlew 会帮助我们下载项目配置文件中的 Gradle 版本,有了 Gradlew 我们就不用自己去安装 Gradle

Gradlew 也方便了在团队开发过程中统一 Gradle 构建的版本号,有利于团队协作

Android 中的 Gradle 结构

上面介绍的知识可以简单概括为:

Android 项目构建需要 Gradle 和 Android Gradle plugin

而 Gradlew 会下载项目配置文件中的 Gradle 版本

现在我们来看一下 Android 中的 Gradle 架构,将理论与实际对应起来

一个普通的 Android 项目结构如下所示:
gradle_art

而 Gradle 和 Android Gradle 插件的版本可以在下图所示的地方配置:
project structure

当然在这里配置的版本号,最终修改的都是下面的文件中的内容

顶级构建文件

顶级 build.gradle 文件位于项目根目录,用于定义适用于项目中所有模块的构建配置

该文件中定义了 Android Gradle 插件的版本,如下所示:

buildscript {
    repositories {	//Android Gradle 插件的下载仓库
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'	//Android Gradle 插件的版本
    }
}

allprojects {	//所有模块共同的配置
    repositories {
        jcenter()
        mavenCentral()
        maven { url "https://jitpack.io" }
        google()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

根据 Android Gradle 插件版本的高低,Android Gradle 插件 保存在不同路径

一些 低版本 的 Android Gradle 插件保存在如下路径:

Android Studio 安装目录\gradle\m2repository\com\android\tools\build\gradle\各版本目录

gradle 跟踪低版本的源码可能找不到java文件,打开了class文件,class文件没有注释,查看不方便

可以在 这个地址 搜索 Android Gradle 插件的groupcom.android.tools.build

找到对应版本的sources文件,下载后放到 Android Gradle 插件相应版本的路径下就能很方便地查看了

一些 高版本 的 Android Gradle 插件保存在如下路径:

C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\com.android.tools.build\gradle\各版本目录

高版本的 gradle 源码都是可以直接查看的

Gradlew 配置文件

文件 gradle-wrapper.properties 中指定了 gradle 的版本,它的内容一般如下所示:

distributionBase=GRADLE_USER_HOME	//保存目录
distributionPath=wrapper/dists	//保存路径
zipStoreBase=GRADLE_USER_HOME	//zip文件保存目录
zipStorePath=wrapper/dists	//zip文件保存路径
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip	// gradle 的版本和下载地址

如果 gradle 下载贼慢,可以先到 这个地址 下载好需要的 gradle 版本

然后修改distributionUrl 为本地路径

下载好的 gradle 保存在如下路径:

C:\Users\Administrator\.gradle\wrapper\dists\gradle-4.6-all

可以发现,这个路径就是文件 gradle-wrapper.properties 中配置的路径

模块级构建文件

模块级 build.gradle 文件位于每个<project>/<module>/目录,用于配置适用于其所在模块的构建设置

可以通过配置这些构建设置来提供自定义打包选项,以及替换 main/应用清单或顶级 build.gradle 文件中的设置

它的内容一般如下:

apply plugin: 'com.android.application'	//应用 Android Gradle 插件,并使 android {} 块生效

android {

	……
	
	defaultConfig{
	
	}
	
	signingConfigs{
	
	}
	
	buildTypes{
	
	}
	
	productFlavors {
	
	}
	
	……
	
}

dependencies {
	
}

Gradle 构建的生命周期

Gradle 的构建过程有着固定的生命周期,理解这些生命周期有助于我们 hook

初始化阶段

创建项目的层次结构,并且为每一个项目创建一个 Project 实例

与初始化阶段相关的脚本文件是 settings.gradle

配置阶段

执行各项目下的 build.gradle 脚本,完成 Project 的配置

构造 Task 任务依赖关系图

执行阶段

执行各 Task

Gradle的使用

依赖配置

依赖配置写在闭包 dependencies {}

Android Gradle 插件 3.0.0 以后的版本有以下变化:

新配置 废弃配置 行为
implementation compile 1. 只在运行时传递依赖 2. 能提升编译速度 3. 大部分时候用这个配置
api compile 编译时和运行时都传递依赖
compileOnly provided 用于只在编译时才需要的依赖
runtimeOnly apk 用于只在运行时才需要的依赖
annotationProcessor compile 用于注解处理器
多渠道

Android Gradle 插件 3.0.0 以后多渠道的写法大致如下:


	flavorDimensions "api"	//风味维度,可以理解为类别名,每种风味必须属于一个维度
	
    productFlavors {
        // 默认
        official {}
        huawei {}
        xiaomi {}
        yingyongbao {}
        wandoujia {}
        productFlavors.all { flavor ->
            flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
            dimension 'api'
        }
    }

渠道很多是用友盟统计的,需要在 AndroidManifest.xml 文件中加入以下占位符

	<meta-data
	    android:name="UMENG_CHANNEL"
	    android:value="${UMENG_CHANNEL_VALUE}" />

按照这种多渠道配置,Sync 后可以选择以下变体进行构建:
在这里插入图片描述
打包后的各渠道包文件夹如下图所示:
在这里插入图片描述

自动命名 apk 文件

Android Gradle 插件 3.0.0 以后变体输出的写法大致如下:

	// 输出例子:Sbingo666_正式包_huawei_v3.6.8.apk
    android.applicationVariants.all { variant ->
        variant.outputs.all {
            if (variant.buildType.name.equals('release')) {
                outputFileName = 'Sbingo666_正式包_' + variant.productFlavors[0].name +
                        "_v" + defaultConfig.versionName + '.apk'
            } else {
                outputFileName = 'Sbingo666_测试包_' + variant.productFlavors[0].name +
                        "_v" + defaultConfig.versionName + '.apk'
            }
        }
    }
统一管理依赖版本

如果项目中有很多个 module,可以在一个文件中统一管理依赖,这样就不用修改多处 module 的 构建文件了

统一管理的方式有多种,这里介绍比较常用的一种:

  1. 新建版本配置文件
    在项目根目录下新建 config.gradle 文件,其中包含了 Android 配置和依赖的版本号,内容大致如下:
ext {
    android = [compileSdkVersion: 28,
               minSdkVersion    : 16,
               targetSdkVersion : 28,
               versionCode      : 1,
               versionName      : "1.0.0"]


    dependencies = ['support-v4'          : 'com.android.support:support-v4:25.2.0',
                    'recyclerview-v7'     : 'com.android.support:recyclerview-v7:25.2.0',
                    'cardview-v7'         : 'com.android.support:cardview-v7:25.2.0',
                    'design'              : 'com.android.support:design:25.2.0',
                    'rxjava'              : 'io.reactivex:rxjava:1.2.2',
                    'rxandroid'           : 'io.reactivex:rxandroid:1.2.1']
}
  1. 在根 build.gradle 文件头部添加应用插件的脚本:
apply from: "config.gradle"
  1. 在相应 modulebuild.gradle 文件中使用配置:
apply plugin: 'com.android.application'

def android_ext = rootProject.ext.android
def library_ext = rootProject.ext.dependencies

android {

	……
	compileSdkVersion android_ext.compileSdkVersion
	
	defaultConfig{
		……
        minSdkVersion android_ext.minSdkVersion
        targetSdkVersion android_ext.targetSdkVersion
        versionCode android_ext.versionCode
        versionName android_ext.versionName
        ……
	}
	……
}

dependencies {
	implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation library_ext['support-v4']
    implementation library_ext['recyclerview-v7']
    implementation library_ext['cardview-v7']
    implementation library_ext['design']
    implementation library_ext['rxjava']
    implementation library_ext['rxandroid']
    ……
}

参考资料

Gradle-plugin
Add build dependencies
变体输出

猜你喜欢

转载自blog.csdn.net/recordGrowth/article/details/85701450