2021年10月份成为兼职Android开发,之前一直没正式系统学习,现在开一个series来记录Android的学习。

Gradle

开始学习android的时候,相信gradle是大家绕不开的一个地方,因为android的环境很难调通,很多依赖下载也是状况百出。但是即使这样,很多人也是选择解决问题后就不去深究背后的原理,选择直接绕过gradle直接写项目,遂在android学习的第一章先学习gradle。 题外话,最新版的springboot已经由maven改为使用gradle来进行构建项目。

什么是Gradle

gradle本质上是个打包工具,结合了ant和maven的优点(没感觉出来)

https://www.zhihu.com/question/30432152

先把普通的gradle目录结构放出来,便于后面的理解。

1
2
3
4
5
6
7
8
9
root:
  gradle:
    wrapper:
      - gradle-wrapper.properties # 指定gradle版本号
      - gradle-wrapper.jar # 安装部署gradle包
  - build.gradle # 构建脚本
  - settings.gradle # 指定工程名
  - gradlew.bat # windows安装gradle命令 去执行jar包
  - gradlew # linux安装gradle命令 去执行jar包

Gradle Wrapper(gradlew)

直到现在见到Gradle Wrapper(包装纸)也很迷惑,不知道这是什么,有什么作用。下面先从官方的解释开始看起:

The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary. As a result, developers can get up and running with a Gradle project quickly without having to follow manual installation processes saving your company time and money.

大意就是Wrapper就是一个invokes(调用)gradle版本号,如果有必要先下载该版本gradle的脚本,解决了手动安装gradle的过程。

gradlew的生成很简单,安装完gradle后执行 gradle wrapper, 生成完wrapper后我们可以看到目录下多了个这样的结构:

1
2
3
4
5
6
7
root:
  gradle:
    wrapper:
      - gradle-wrapper.properties
      - gradle-wrapper.jar
  - gradlew.bat
  - gradlew
  • gradle-wrapper.properties: 顾名思义,gradlew的配置项

GRADLE_USER_HOME 默认~/.gradle/,如果启动时指定其它的则重新下载所有到新目录

1
2
3
4
5
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+ distributionBase: 下载的Gradle压缩包后解压存储的主目录
+ distributionPath: Gradle的压缩包的路径
+ distributionUrl: Gradle下载地址
+ zipStoreBase: 存放zip压缩包
+ zipStorePath: 存放zip压缩包
  • gradle-wrapper.jar: 安装gradle的jar包

  • gradlew.bat: windows下生成bat文件,这个bat文件里的脚本就是去执行jar包完成gradle的安装和部署。

  • gradlew:linux/mac下的执行文件

settings.gradle

settings.gralde用来配置项目的模块,下面是一个真实的setting.gradle:

1
include ':app', ':sdk'
  • gradle支持多模块构建,settings.gradle配置模块

  • settings文件在初始化阶段执行,创建Settings对象,在执行脚本时调用该对象的方法 Settings.include(String… projectPath)

    • ‘:app’ = ‘./app’

build.gradle

build.gradle配置文件分为两个级别的,一个是项目级别的,一个是模块级别的。先看项目级别的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.5.0"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        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 {
        google()
        mavenCentral()
    }
}

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

注意第一行的注释,这是一个顶层的构建文件,包含了一些通用的配置对所有的模块。

  • buildScript: 包含了kotlin的版本和kotlin的依赖

  • allProjects: 引入了所有的模块都使用的通用的依赖

  • task clean: 这里需要注意的是gradle的编译和构建由一个个命令组成,我们在build的时候也可以看到,每个task具体的作用这里不深究,这里的clean的task实际上就是实现了maven clear同样的作用。如果自己需要其它的task,也可以直接在build.gradle里面编写,具体的语法是groovy。

再看模块级别的build.gradle

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 31
    buildToolsVersion '30.0.2'

    defaultConfig {
        applicationId "com.example.android.diceroller"
        minSdkVersion 24
        targetSdkVersion 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    ndkVersion '23.1.7779620'
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:+'
    implementation 'androidx.appcompat:appcompat:+'
    implementation 'com.google.android.material:material:+'
    implementation 'androidx.constraintlayout:constraintlayout:+'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:+'
    androidTestImplementation 'androidx.test.espresso:espresso-core:+'
}