Gradle全解

我们Android项目里会有Java/Kotlin代码,Xml文件,各种图片音视频资源文件等,那么Gradle 就是来帮我们打包生成 apk 的一个程序。

Gradle中,每一个待编译的工程都叫一个Project。每一个Project在构建的时候都包含一系列的Task。比如一个Android APK的编译可能包含:Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等。一个Project到底包含多少个Task,其实是由编译脚本指定的插件决定。插件是什么呢?插件就是用来定义Task,并具体执行这些Task的东西。

Gradle与前身构建工具Maven

Gradle抛弃了Maven的基于XML的繁琐配置,众所周知XML的阅读体验比较差,对于机器来说虽然容易识别,但毕竟是由人去维护的。取而代之的是Gradle采用了领域特定语言Groovy的配置,大大简化了构建代码的行数。

Gradle 是个程序、Groovy 是特定领域 DSL 语言

Gradle 是运行在 JVM 实例上的一个程序,内部使用 Groovy 语言
Groovy 是一种 JVM 上的脚本语言,基于 java 扩展的动态语言

gradle的生命周期

  1. initalization初始化阶段: 解析整个工程中所有Project,构建所有的Project对应的project对象,这个阶段主要就是解析setting.gradle文件
  2. Configuration配置阶段:解析所有的projects对象中的task,构建好所有的task拓扑图,主要解析各个project下的build.gradle文件
  3. Execution执行阶段:执行具体的的task及其依赖task

在项目的build.gradle中监听gradle的生命周期回调:

beforeEvaluate {
    println '配置阶段开始前的监听回调'
}

afterEvaluate {
    println '配置阶段完成以后的回调'
}

gradle.buildStarted {
    println 'build开始的回调监听'
}

gradle.buildFinished {
    println 'build完毕后的回调监听'
}

gradle.beforeProject {
    println 'gradle执行前的回调监听'
}

gradle.afterProject {
    println 'gradle执行前的回调监听'
}
gradle方法:
/**
 * 获取所有Project
 */
getAllprojects().eachWithIndex { Project entry, int i ->
}

/**
 * 获取所有子Project
 */
getSubprojects().eachWithIndex { Project entry, int i ->
}

/**
 * 配置subproject的所有project(module)
 */
subprojects {

}

/**
 * 获取根Project
 */
getRootProject()
gradle.properties声明,可在gradle中引用该配置
#dev          开发环境
#beta         测试环境
#release      正式上线环境
NET_TYPE=dev
android.useAndroidX=true
android.enableJetifier=true
android.injected.testOnly=false
kotlin.code.style=official
  • gradle仓库

在项目的根build.gradle文件中,配置需要从哪里的仓库下载jar包

repositories {
        //构建项目时会拉取gradle资源,而goole和jcenter在国内的网络环境并不好,容易出现包拉取失败的问题,那么就可以使用国内阿里的镜像。
        //repositories里仓库具有从上到下先后获取顺序
        maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        maven{ url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        google()
        jcenter()
}
Gradle文件配置层级:
  • 一个工程包含一个setting.gradle文件和一个build.gradle文件。可能有多个Module,每个Module有自己的一个build.gradle。
  • setting.gradle: setting文件定义哪些module需要加入到编译过程
  • 工程的build.gradle:该build文件最终会被应用到所有Module中
  • Gradle Wrapper: 对Gradle一层包装,便于使用统一Gradle构建

gradle-wrapper.jar:具体业务逻辑实现的jar包
gradle-wrapper.properties:配置文件,包含篇配置信息如下图:


gradle文件配置示例:

apply plugin: 'com.android.application'

android {

    signingConfigs {
        config {
            keyAlias ''
            keyPassword ''
            storeFile file('keystore.jks')
            storePassword ''
        }
    }

    compileSdkVersion 27
    defaultConfig {
        applicationId ""
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
        flavorDimensions "versionCode"

        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true

        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11 -frtti -fexceptions"
            }
        }

        ndk {
            abiFilters 'armeabi-v7a'
        }

        lintOptions {
            abortOnError false
        }
    }

    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

    buildTypes {
        release {
            minifyEnabled true   
            shrinkResources true   
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }
        debug {
            minifyEnabled false
            signingConfig signingConfigs.config
        }
    }

    flavorDimensions "tier" 
    productFlavors {
        yingyongbao { dimension "tier" }
    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
}

android.lintOptions {   //忽略中英文大小写
    checkReleaseBuilds false
    abortOnError false
}

allprojects {
    repositories {
        mavenCentral()
    }
}

repositories {
    flatDir {
        dir 'libs'

    }
}

dependencies {
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.jakewharton:butterknife:7.0.1'
}

配置说明:

apply plugin:

表明应用的插件的类型,工程项目是com.android.application类型,而Module则是com.android.library

android

这是编译文件中最大的代码块,关于android 的所有特殊配置都在这里

defaultConfig

程序的默认配置

externalNativeBuild

native编译支持
常用属性
1.cmake:CMake工具编译选项。
2.ndkBuild:ndk-build选项。

buildTypes

分为release版本和debug版本
常用属性:

minifyEnabled 是否开启混淆
shrinkResources 是否去除无用资源
signingConfigs 签名配置信息
name:build type的名字
proguardFiles:混淆文件

lintOptions

Lint工具可选项参数
常用属性
abortOnError false如果发现错误,lint工具是否应该退出这个程序。true表示退出。

productFlavors

项目打包变体配置

flavorDimensions "tier" 
productFlavors {
        yingyongbao { dimension "tier" }
    }
    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
signingConfig

签名配置信息

signingConfigs {
        config {
            keyAlias ''
            keyPassword ''
            storeFile file('keystore.jks')
            storePassword ''
        }
    }

keyAlias 签名key的别名
keyPassword 签名key的密码
storeFile file 签名key的路径
storePassword store签名密码
v1SigningEnabled:是否使用jar签名(又名v1签名)
v2SigningEnabled:是否使用apk签名(又名v2签名)

repositories

代码仓库:Gradle支持从maven中央仓库和JCenter上获取构件

dependencies

dependencies属于gradle 的依赖配置。它定义了当前项目需要依赖的其他库。
我们在引用库的时候,每个库名称包含三个元素:发布者标识:库名:版本号
例如:

implementation 'com.alibaba:fastjson:1.2.8'

如果为implementation 'com.alibaba:fastjson:1.2.+'表示会使用库的最新版本。但是每次编译都要去做网络请求查看是否有新版本导致编译减慢。

gradle.properties配置
  • 加大可用编译内存:
    org.gradle.jvmargs=-Xmx1024m

  • 开启编译守护进程
    org.gradle.daemon=true

  • 开启并行编译
    org.gradle.parallel=true

Gradle Plugin

Gradle是一个框架,作为框架,它负责定义流程和规则。而具体的编译工作则是通过插件的方式来完成的。比如编译Java有Java插件,编译Groovy有Groovy插件,编译Android APP有Android APP插件,编译Android Library有Android Library插件。

  • 自定义task
task taskName {
    //do some things
 }

gradle中创建task的两种方式

task myTask {
    println '执行myTask'
}

tasks.create(name: 'myTask') {
    println '执行myTask'
}

定义简单task

//定义 task , 名字 hello
task hello {
    println "hello world"
}

//定义 task,名字 hello
task(hello2) {
    println "hello world2"
}

//定义 task,名字 hello3
task ('hello3') {
    println "hello world3"
}

task 本质上又是由一组被顺序执行的 Action 对象构成,Action其实是一段代码块,类似于Java中的方法。

task actionUse {
    //在Action 队列头部添加Action
    doFirst {

    }
    //在Action 队列尾部添加Action
    doLast {

    }
    //创建一个 Action , 添加到 Action 列表的头部
    doFirst(new Action<Task>() {
        @Override
        void execute(Task task) {

        }
    })
}
参考

https://mp.weixin.qq.com/s/UlnHuM2-Dqad3MXE77xJyg

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 176,548评论 25 709
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 14,519评论 2 59
  • 说明 本文主要介绍和Gradle关系密切、相对不容易理解的配置,偏重概念介绍。部分内容是Android特有的(例如...
    jzj1993阅读 16,066评论 1 62
  • 在 Android Studio 构建的项目中,基于 Gradle 进行项目的构建,同时使用 Android DS...
    Ant_way阅读 12,145评论 0 16
  • 3. By落花水留痕 “老师?” 在一片黑暗中默默垂泪的柏木,被一声怯怯的呼唤吓的怔住了。她不想让人看见自己现在的...
    红白的書籤阅读 3,126评论 0 1

友情链接更多精彩内容