Android Gradle 学习笔记整理

前言

Gradle 是将软件编译、测试、部署等步骤联系在一起自动化构建工具。
对于Android开发人员已经了解build.gradle 的 android{} 和 dependencies{} ,但是他的编译过程是什么样的?这个过程中可以干些什么事了解吗?
此文是学习Gradle时的学习笔记,让你重新认识Gradle,让Gradle加快并提效构建你的项目。此时分享给大家,与大家共勉

此笔记主要内容如下

  • Gradle 最基础的一个项目配置

  • Groovy 基础语法 并解释 apply plugin: 'xxxx’和dependencies{}

  • Gradle Project/Task 并自定义Task和Plugin

  • 自定义一个重命名APP名的插件 流程

  • APT 技术- Java AbstractProcessor

  • Android 字节码增强技术 - Transform (Android 中使用字节码增强技术)

文章内容略长,如果你已经掌握Gradle基础知识,可以直接通过目录查看你想看的内容,回顾或者学习都还不错。

初识Gradle 项目构建配置

gralde项目结构


如图所示,是一个比较小的gradle配置,这里主要说两部分

  1. 绿色部分: gralde版本配置及gralde所需要的脚本,其中gradlew为linux/mac下的脚本,gradle.bat为windows下所需的脚本
  2. 红色部分:settings.gradle 为根项目的项目配置,外层的build.gradle为根项目的配置,内层的build.gradle为子项目的配置

gradle 配置顺序

gralde的项目配置是先识别 settings.gradle,然后在配置各个build.gradle.
为了说明构建执行顺序,在上述最基础的gradle项目结构里面设置了对应的代码

// settings.gradle
println "settings.gradle start"
include ':app'
println "settings.gradle end"
//root build.gradle
println "project.root start"
buildscript {
    repositories {
    }
    dependencies {
    }
}

allprojects {
}
println "project.root end"
//app build.gradle
println "project.app start"
project.afterEvaluate {
    println "project.app.afterEvaluate print"
}
project.beforeEvaluate {
    println "project.app.beforeEvaluate print"
}
println "project.app end"

如果是mac/linux,执行./gradlew 得到如下结果:

settings.gradle start
settings.gradle end

> Configure project :
project.root start
project.root end

> Configure project :app
project.app start
project.app end
project.app.afterEvaluate print

Groovy 语法

下面讲一些关于groovy的语法,可以打开Android Studio Tools-> Groovy Console练习Groovy 语法 ,如下

可选的类型定义,可以省略语句结束符分号(;)

int vs = 1
def version = 'version1'

println(vs)
println(version)

括号也是可选的

println vs
println version

字符串定义

def s1 = 'aaa'
def s2 = "version is ${version}"
def s3 = ''' str
is
many
'''
println s1
println s2
println s3

集合

def list = ['ant','maven']
list << "gradle"
list.add('test')
println list.size()
println list.toString()
//map
def years = ['key1':1000,"key2":2000]
println years.key1
println years.getClass()

输出结果

[ant, maven, gradle, test]
1000
class java.util.LinkedHashMap

闭包

groovy语法中支持闭包语法,闭包简单的说就是代码块,如下:

def v = {
    v -> println v
}
static def testMethod(Closure closure){
    closure('闭包 test')
}
testMethod v

其中定义的v就为闭包,testMethod 为一个方法,传入参数为闭包,然后调用闭包.

解释 apply plugin: 'xxxx’和 dependencies{}

准备工作,看gradle的源码

我们先把子项目的build.gradle改为如下形式

apply plugin: 'java-library'
repositories {
    mavenLocal()
}
dependencies {
    compile gradleApi()
}

这样,我们就可以直接看gradle的源码了,在External Libraries里如下

解释

进入build.gradle 点击apply 会进入到gradle的源码,可以看到

//PluginAware
 /**
     * Applies a plugin or script, using the given options provided as a map. Does nothing if the plugin has already been applied.
     * <p>
     * The given map is applied as a series of method calls to a newly created {@link ObjectConfigurationAction}.
     * That is, each key in the map is expected to be the name of a method {@link ObjectConfigurationAction} and the value to be compatible arguments to that method.
     *
     * <p>The following options are available:</p>
     *
     * <ul><li>{@code from}: A script to apply. Accepts any path supported by {@link org.gradle.api.Project#uri(Object)}.</li>
     *
     * <li>{@code plugin}: The id or implementation class of the plugin to apply.</li>
     *
     * <li>{@code to}: The target delegate object or objects. The default is this plugin aware object. Use this to configure objects other than this object.</li></ul>
     *
     * @param options the options to use to configure and {@link ObjectConfigurationAction} before “executing” it
     */
    void apply(Map<String, ?> options);

用Groovy 语法很清楚的解释,apply其实就是一个方法,后面传递的就是一个map,其中plugin为key.

那么dependencies{}也是一样

//Project
/**
     * <p>Configures the dependencies for this project.
     *
     * <p>This method executes the given closure against the {@link DependencyHandler} for this project. The {@link
     * DependencyHandler} is passed to the closure as the closure's delegate.
     *
     * <h3>Examples:</h3>
     * See docs for {@link DependencyHandler}
     *
     * @param configureClosure the closure to use to configure the dependencies.
     */
    void dependencies(Closure configureClosure);

dependencies是一个方法 后面传递的是一个闭包的参数.

问题:思考那么android {}也是一样的实现吗? 后面讲解

Gradle Project/Task

在前面章节中提到gralde初始化配置,是先解析并执行setting.gradle,然后在解析执行build.gradle,那么其实这些build.gradle 就是Project,外层的build.gradle是根Project,内层的为子project,根project只能有一个,子project可以有多个.

我们知道了最基础的gradle配置,那么怎么来使用Gradle里面的一些东西来为我们服务呢?

Plugin

前面提到apply plugin:‘xxxx’,这些plugin都是按照gradle规范来实现的,有java的有Android的,那么我们来实现一个自己的plugin.

把build.gradle 改为如下代码

//app build.gradle
class LibPlugin implements Plugin<Project>{
    @Override
    void apply(Project target) {
        println 'this is lib plugin'
    }
}
apply plugin:LibPlugin

运行./gradlew 结果如下

> Configure project :app
this is lib plugin

Plugin 之Extension

我们在自定义的Plugin中要获取Project的配置,可以通过Project去获取一些基本配置信息,那我们要自定义的一些属性怎么去配置获取呢,这时就需要创建Extension了,把上述代码改为如下形式。

//app build.gradle
class LibExtension{
    String version
    String message
}
class LibPlugin implements Plugin<Project>{
    @Override
    void apply(Project target) {
        println 'this is lib plugin'
        //创建 Extension 
        target.extensions.create('libConfig',LibExtension)
        //创建一个task
        target.tasks.create('libTask',{
           doLast{
               LibExtension config = project.libConfig
               println config.version
               println config.message
           }
        })
    }
}
apply plugin:LibPlugin
//配置
libConfig {
    version = '1.0'
    message = 'lib message'
}

配置完成后,执行./gradlew libTask
得到如下结果

> Configure project :app
this is lib plugin
> Task :lib:libTask
1.0
lib message

看完上述代码,我们就知道android {} 其实他就是一个Extension, 他是由plugin ‘com.android.application’或者’com.android.library’ 创建。

Task

上述代码中,创建

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值