《Gradle for Android》笔记(2):自定义构建基础

cover

Android项目中的Gradle文件

  • 三个默认生成的文件。

    1
    2
    3
    4
    5
    MyApp 
    ├── build.gradle
    ├── settings.gradle
    └── app
    └── build.gradle
  • settings.gradle文件在Initialization阶段执行,定义了这次构建包含的module。

    1
    2
    // 只有一个module的settings.gradle
    include ':app'
  • 顶层build.gradle文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 构建脚本,注意这里的配置是应用到构建系统本身的(Gradle),而不是项目。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}

// 应用到所有module(这里加做allprojects是因为对于Gradle来说,module也是一个Gradle project)
allprojects {
repositories {
// 所有module均使用JCenter作为依赖源
jcenter()
}
}
  • buildscript块是实际构建的配置存在的地方。
  • Module层的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
    apply plugin: 'com.android.application'

    android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
    // 应用唯一标识
    applicationId "com.gradleforandroid.gettingstarted"
    // 最小支持的API版本
    minSdkVersion 14
    // 表示应用基于哪个版本的SDK构建,运行应用的系统不会为这个应用提供新的特性
    // 这个配置和compileSdkVersion无关
    targetSdkVersion 22
    versionCode 1
    versionName "1.0"
    }
    buildTypes {
    release {
    minifyEnabled false
    proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'
    }
    }
    }

    // 依赖是Gradle的标准配置项,所以不在Android配置块里面。
    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    }

这里可以使用Android Application插件就是因为在顶层的build.gradle文件中添加了Android构建工具依赖。

  • defaultConfig 部分用来覆盖AndroidManifest中的配置(Eclipse时代)。
  • 在使用Gradle之前的Android构建系统,会把AndroidManifest中的package用作两个用途:
    1. 用作应用的唯一标识。
    2. 用作应用R文件的包名。
  • 使用Gradle作为默认构建工具之后,AndroidManifest中的package字段依然在源码层面作为应用的包名使用,包括R文件。而 applicationId将作为应用的唯一标识用以区分多个App。这个设定将有助于构建一个应用的多个变体(比如收费、免费)。

Android项目相关的Gradle Tasks

  • 列出项目中的Tasks
    • ./gradlew tasks
    • ./gradlew tasks --all
  • 模拟执行/预执行Task(dry-run),将会打印Task的执行步骤。
    • ./gradlew [TASK NAME] -m / —dry-run
  • Android插件基于Java基础插件开发,Java基础插件又基于基础插件开发,他们都定义了一些基本的Tasks,但是并不包含实现,只是定义了协议。Base插件的实现,要实现这些Tasks。基础插件中的Tasks:assembleclean,Java基础插件中的Tasks:checkbuild
  • Android的基础Tasks的实现
    • assemble:针对每个构建类型生成APK文件。
    • clean:清除构建产物。
    • check:执行Lint检查。
    • build:执行assemble和check。
  • 其他重要的Tasks
    • connectedCheck:在设备或模拟器上运行测试。
    • deviceCheck:这是一个占位,其他插件可以实现在远程机器上进行测试。
    • installDebuginstallRelease:安装对应的版本。
    • 所有install Task都有一个对应的uninstall Task。
  • check Task会在app/build/outputs目录下生成lint-results.xml文件,作为检查的结果报告。

自定义构建

  • 修改任何构建相关选项,都应该同步项目。Sync命令实际上是运行了generateDebugSources Task。
  • 可以使用Project Structure窗口修改比如混淆、签名等配置,这些配置都将写入Gradle配置文件。

自定义BuildConfig常量和资源(在Android项目中使用)

  • SDK工具更新到17以后,构建工具会生成一个BuildConfig类,这个类会包含一个DEBUG常量。可以用来判断是否为debug类型的构建,比如log的时候。
  • buildTypes块中可以配置不同的常量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    android { 
    buildTypes {
    debug {
    buildConfigField "String", "API_URL", "\"http://test.example.com/api\""
    buildConfigField "boolean", "LOG_HTTP_CALLS", "true"
    }

    release {
    buildConfigField "String", "API_URL", "\"http://example.com/api\""
    buildConfigField "boolean", "LOG_HTTP_CALLS", "false"
    }
    }
    }
  • 下面这行配置创建了一个字符串常量,包含服务器的API地址。

    1
    buildConfigField "String", "API_URL", "\"http://test.example.com/api\""

字符串的值,必须由转移的双引号包裹。

  • 配置资源的值:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    android {
    buildTypes {
    debug {
    resValue "string" "app_name" "Example_DEBUG"
    }
    release {
    resValue "string" "app_name" "Example"
    }
    }
    }

注意,和上面的字符串常量不同,这里的字符串资源,不需要双引号转义,因为资源的格式value=“”已经包含了双引号。

  • 在buildConfig中配置常量:
    • buildConfigField:会编译成[TYPE] [NAME] [VALUE]
    • resValue:会编译成[NAME]=“[VALUE]”

自定义构建属性(在Tasks中使用)

  • 在顶层的build.gradle中可以配置应用到所有Module的配置项,比如Android编译版本。
  • Gradle的Project对象允许增加额外属性,任意build.gradle文件都可以通过ext配置块给Project对象增加自定义属性。全局应用配置的更好的实践,就是使用自定义属性。

    1
    2
    3
    4
    ext {
    compileSdkVersion = 22
    buildToolsVersion = "22.0.1"
    }
  • 定义好了属性之后,在Module中的使用方法:

    1
    2
    3
    4
    android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    }
    1. 使用自定义属性时,可以直接使用属性名,如:compileSdkVersion
    2. Module中可以通过ext定义相同的属性,如果顶层也有相同配置,会被Module中的配置覆盖。
    3. 上面代码中, rootProject.ext.compileSdkVersion将会强制使用rootProject中的ext定义的属性,这个属性并不会被Module中的同名属性覆盖。
  • 三种常用的自定义属性的方法
    1. ext代码块
    2. gradle.properties 文件(同级目录下)propertiesFileProp = Property from gradle.properties file.
    3. 命令行 -P 参数 ./gradlew exampleTask -PcmdProp='Properties from CLI.'

其他文章