Android Gradle配置分析

2021-12-16 17:35:50 浏览数 (1)

前言

Android 开发目前大家使用的IDE是Android Studio,所以和Gradle打交道就是必不可少的了。

大部分时间可能我们关注的都是业务代码的开发,然而了解gradle可以帮助我们更好的构建我们的项目

关于Gradle

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML

这是维基百科上对Gradle的描述,可以了解到:

  • gradle 是个构建工具,不是一种语音。

gradle 构建使用到是 Groovy 语言。

Android项目中gradle配置

Android 工程中gradle配置文件有build.gradlesettings.gradlegradle-wrapper等如下图:

  • settings.gradle: 工程配置,多projrct项目中配置项目结构。 settings.gradle 配置文件在主工程中,文件中可以查看其他的配置project
  • build.gradle:project工程配置文件,配置工程依赖编译等信息

tip:

  1. 单project项目,只要一个build.gradle文件就OK了。 多projec项目需要由settings.gradle来配置多个build.gradle
  2. 查找 settings.gradle 的顺序是:当前目录 -> 兄弟目录 master -> ⽗目录
代码语言:javascript复制
// `settings.gradle` 配置文件
include ':app'    
rootProject.name='Demo'

根目录下到gradle配置(Project: Demo)如下(配置的用途见注释):

代码语言:javascript复制
//  主项目中build.gradle 配置文件
buildscript {
    ext.kotlin_version = '1.3.61'
   
    repositories {
        // 这里配置的是  下面 dependencies中配置的依赖的仓库地址 
        google()
        jcenter()
        
    }
    dependencies {
        // 这里的引入的依赖, 是为了使用  gradle 和 kotlin 的  plugin。 
        //  例如: apply plugin: 'com.android.application'  , apply plugin: 'kotlin-android'
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        // 针对项目的仓库配置 , 每一个model 都使用这个仓库
        google()
        jcenter()
        
    }
}

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

app model 中build.gradle配置如下(用途见注释)

代码语言:javascript复制
// 这里使用的 plugin ,需要在根目录下的gradle中配置引用 
apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.tencent.demo"
        minSdkVersion 17
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        // buildType 默认有 debug 和 release 两个, 也可以进行自定义扩充
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {

    // compile : 已经被废弃 
   // api:  是 compile 的替代用法, 会传递依赖
   // implementation : 不传递依赖。 
   //   传递依赖时,二级项目的改动会导致0级项目的重新编译; 不传递依赖时二级项目的改动不会导致0级项目的重新编译

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

tips:

buildTypesFlavor 的用法可以参考 Android 构建多APK

gradle 执行阶段分析

  • 初始化阶段:执⾏ settings.gradle,确定主 project 和子 project
  • 定义阶段: 执行每个 project 的 bulid.gradle,确定出所有 task 所组成的有向无环图
  • 执⾏阶段:按照上一阶段所确定出的有向⽆环图来执⾏指定的 task
gradle task 介绍

task 的写法如下:

代码语言:javascript复制
task test() {
    print('初始化代码')
    doFirst {
        print('doFirst')
    }
    doLast {
        print('doLast')
    }
}

/*
* 1. doFirst() 和 doLast() 在 task 执行过程中被执⾏,在执行阶段(第三阶段)执行,如果用户没有直接或者间接执行task,那这部分的代码块就不会执行
* 2. 初始化代码,在task创建的时候就会被执行,是在定义阶段(第二阶段)执行
* 3. doFirst()  是插入在队列的前面,doLast()是插入到队列的后面
*/
 

task clean(type: Delete) {
    delete rootProject.buildDir
   // tasks["nameA"].dependsOn nameB
}

/*
*  1.  task 可以使用 task taskA(dependsOn: b) 的形式来指定依赖。
*  2.  tasks["nameA"].dependsOn nameB 也可以使用这种方式指定依赖关系
*  3. 指定依赖后,task 会在⾃己执⾏前先执⾏⾃己依赖的 task
*/

android 中可以使用如下命令执行task

代码语言:javascript复制
 $ ./gradlew assembleDebug

BUILD SUCCESSFUL in 5s
25 actionable tasks: 3 executed, 22 up-to-date
  • 在第一二之间插入相关修改
代码语言:javascript复制
// 修改写入settings.gradle 最后。 
  • 在第二三之间插入相关修改
代码语言:javascript复制
 afterEvaluate { 
      // 插⼊入代码
}
例如修改apk名称:

app build.gradle 种写法:
android.applicationVariants.all {
    variant ->
        variant.outputs.all {
            //在这里修改apk文件名
            outputFileName = "${variant.name}-v${variant.versionName}.apk"
        }
}

// 自定义文件种实现方法 
project.afterEvaluate {
    android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def buildNoSuffix = System.env.BuildNo ? ".${System.env.BuildNo}" : ".0"
            //重命名为
            def releaseApkName = "${variant.name.capitalize()}_${variant.mergedFlavor.versionName}${buildNoSuffix}.apk"
            println "releaseApkName: "   releaseApkName   ", buildNoSuffix:"   buildNoSuffix
            outputFileName = releaseApkName
        }
    }
}

0 人点赞