android gradle 从入门到gg 1

28
6/9/22 刘刘 IPD 刘刘刘刘刘 Android Gradle 刘刘刘刘 GG 刘1刘: Greet

Upload: jween-lau

Post on 11-Apr-2017

1.313 views

Category:

Mobile


4 download

TRANSCRIPT

Page 1: Android gradle 从入门到gg 1

Tuesday, May 2, 2023

刘俊IPD 创新产品部

Android Gradle从入门到 GG

第 1 课 : Greet

Page 2: Android gradle 从入门到gg 1

介绍 Android Gradle 插件的基本 DSL 使用第 1 课 : Greet

Page 3: Android gradle 从入门到gg 1

引用插件buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.0-beta3'

// NOTE: Do not place your application dependencies here; // they belong in the individual module build.gradle files }}

Gradle 每次运行的时候 , 初始化之时 , 将 android gradle jar包加载到 Gradle 运行时环境中 , 而插件就在这些 jar 包内Android Studio 新建的工程会自动在 rootProject 的build.gradle 中生成以上脚本 ( 一般就是根目录的 build.gradle中 )

Page 4: Android gradle 从入门到gg 1

引用插件

apply plugin 之后 , 你就可以使用 android { // configurations}

DSL 入口了

apply plugin: 'com.android.application'

Page 5: Android gradle 从入门到gg 1

引用插件

-1. 很可惜 , android gradle 相关插件并不在 GPCR 里-2. 此处的 id 是 apply 的插件 id, 并不是 Artifact Id, 因为一个 Artifact 的 Jar 包 , 里面可以有几个插件 , 比如 android 的插件 id com.android.application 和 com.android.library 都在 'com.android.tools.build:gradle:2.1.0-beta3'这个 artifact 里面

plugins { id "com.android.application" version "2.1.0-beta3"}

对于 Gradle Plugin Central Repository(plugins.gradle.org) 里的插件 , 可以简化为 plugins { id “Id” version “ver”}

Page 6: Android gradle 从入门到gg 1

Artifact

'com.android.tools.build:gradle:2.1.0-beta3@jar'

group:id:version:ext group: 类似 android packageNameid: 该 jar 包的名字 , 类似 android applicationNameversion: 版本号 , 类似 android versionNameext: 扩展 , 比如 jar, aar, txt 等文件扩展 , 比如某个Android 库 , 既提供了 jar 包 , 也提供了 aar 包 , 这时就可以通过 ext 来区分你想要哪一个

Page 7: Android gradle 从入门到gg 1

Artifact

'com.android.tools.build:gradle:2.1.0-beta3'

dependencies { compile 'com.meizu.cloud.pushsdk:internal:3.0.3-beta@aar' proguard 'com.meizu.cloud.pushsdk:internal:3.0.3-beta@pro' ...

compile 'io.reactivex:rxjava:1.1.3'

compile(group:'io.reactivex', id: 'rxjava', version: '1.1.3')

一个 Artifact 依赖 , 可以使用 group:id:version:ext 来定位到

等价于

Page 8: Android gradle 从入门到gg 1

Artifact

compile 'io.reactivex:rxjava:1.1.3'

compile "io.reactivex:rxjava:1.1.+" // 1.1. 最新版本 **compile "io.reactivex:rxjava:1.+" // 1. 最新版本 **compile "io.reactivex:rxjava:+" // 最新版本在 Android Studio 中 , 使用了 + 号的依赖引用 , 会被标黄警告在版本管理中 , + 号会导致你的 TAG 分支 , SNAPSHOT 无法百分百还原当时的编译所以 , 尽量避免使用 +

Page 9: Android gradle 从入门到gg 1

repositories {}

repositories { jcenter()}

dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.android.support:design:23.3.0'}

dependencies 中的远程模块依赖 , 来源在 repositories 中声明但是 repositories 是 project 的入口 , DSL 中 project 可以省略即 repositories {} 等价于 project.repositories {}这意味着 , 你只能对当前 build.gradle 配置的 project 有用其他模块 , 你得重新定义它的 repositories {}

Page 10: Android gradle 从入门到gg 1

repositories {}

而之前讲到过 , buildscript {} 是在 Gradle 初始化的时候首先加载buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.0-beta3' }}buildscript{} 中配置的运行时环境依赖 , 对所有模块都有效

allprojects { repositories { jcenter() }}

allprojects{}: 该 Gradle DSL 入口的意思是对 project( 模块 ) 及其子模块都配置将通用的配置放在 rootProject 的allprojects 中吧

Page 11: Android gradle 从入门到gg 1

休息时间课程的随堂 Sample 以及 presentation 在如下 git 中http://git.ipd.meizu.com/AnR/android-gradle-samples

[Github 用户移步 ] https://github.com/Jween/android-gradle-samples

Page 12: Android gradle 从入门到gg 1

android { }

defaultConfig { }: 默认配置 , 所有 flavor 都会继承sourceSets { }: 对代码 / 资源的配置 , android 重新对 gradle sourceSets 进行了针对 Android 的实现 , 叫做 AndroidSourceSetproductFlavors { }: 模块所有 flavor, 不同的 flavor, 可以打包出不同的 apkbuildTypes { }: 模块所有 build 类型 , 不同的类型 , 可以打包出不同的 apksigningConfig { }: App 模块打包 apk 的签名配置splits { }: Apk 分割 , 全资源 apk, 根据分辨率与 abi 分割成若干个小 apk*Options { }: dexOptions { }, packagingOptions { }, aaptOptions { }, lintOptions { }, compileOptions { }, adbOptions { }, testOptions { }

你可以在 http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.BaseExtension.html 这里查看详细的 DSL, 本节课只讲常用到的 android DSL, 标红的重点讲述

Page 13: Android gradle 从入门到gg 1

android.defaultConfig { }defaultConfig {

applicationId "com.meizu.sample.basicdsl" minSdkVersion 22 targetSdkVersion 23 versionCode 1 versionName "1.0"}

以上是 Android Studio 新建一个工程的时候 , 自动配置的 , library 模块的话无法配置 applicationId, 毕竟 library 不是 application为了方便理解 , 先抛出一些概念1. defaultConfig 本质上就是 ProductFlavor2. 把 src/main (android.sourceSets.main) 看作是默认的 flavor

source set, 那么 , defaultConfig 就是对 main 这个 flavor 的配置3. 等会儿讲完 ProductFlavor, 我们再回来看看 defaultConfig

Page 14: Android gradle 从入门到gg 1

android.productFlavors { }假设我们开发了一款新产品 , 需要区分免费版与旗舰版怎么办 ?

productFlavors { free { // 免费版本 }

utlra { // 旗舰版本 }}

android.sourceSets.free { }

android.sourceSets.ultra { }

上一节课 , 我们讲了对 sourceSets.main { } 的一些配置当我们添加了 free 与 ultra 之后 , 你同样可以配置 sourceSets.free { } 以及 sourceSets.ultra { }默认的路径在 main 文件夹同级目录各 flavor 同名文件夹

Page 15: Android gradle 从入门到gg 1

android.productFlavors { }我们希望区分免费版与旗舰版的包名怎么办 ?

productFlavors { free { // 免费版本 applicationIdSuffix ".free" // 免费版包名后缀 .free }

utlra { // 旗舰版本 applicationIdSuffix ".ultra" // 旗舰版包名后缀 .ultra

}}

同理 , 你可以区分应用版本 , Android min targe 版本等 , 你可以区分签名 signingConfig, 区分http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.ProductFlavor.html 中的一切

Page 16: Android gradle 从入门到gg 1

android.productFlavors { }与此同时 , Gradle 会自动生成一个 BuildConfig 类 , 包含当前选定的 variant 的 applicationId, Debug 开关 , flavor, buildType, 版本等public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPLICATION_ID = "com.meizu.sample.basicdsl.free"; public static final String BUILD_TYPE = "debug"; public static final String FLAVOR = "free"; public static final int VERSION_CODE = 1; public static final String VERSION_NAME = "1.0";}

选择 Build Variant 一般在 Android Studio 左下角

Page 17: Android gradle 从入门到gg 1

android.buildTypes { }

我们可以看到 Build Variant选定的是 freeDebug

buildTypes 默认有 debug 和 release BuildType 类似 ProductFlavor, 但是多了与编译深度相关的 proguard 代码混淆 , 资源 Shrink, debug 开关 , 等等

buildTypes { release { minifyEnabled true // 代码混淆 shrinkResources true // 移除没用到的资源和代码 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }}

Page 18: Android gradle 从入门到gg 1

Build Variant

我们可以看到 Build Variant选定的是 freeDebug

Build Variant = [flavors, buildTypes].combinations()

[['a', 'b'],[1, 2, 3]].combinations() == [['a', 1], ['b', 1], ['a', 2], ['b', 2], ['a', 3], ['b', 3]]

[[free, ultra], [debug, release]].combinations() == [[free,debug], [ultra, debug], [free, release], [ultra, release]] freeDebug, freeRelease, ultraDebug, ultraRelease

Page 19: Android gradle 从入门到gg 1

Build Variant

variant! 想想 groovy 的 combinations!

flavor buildType variant

free debugfreeDebug

freeRelease

ultra releaseultraDebug

ultraRelease

Page 20: Android gradle 从入门到gg 1

Build Variant

记住 : 当你在 Build Variant 里面选定了一个 Variant 的时候 , 比如 , 这里的 freeDebug, Android Studio 当前的对项目的配置就是根据 free 的 flavor 以及 debug 的 buildType 来的 , 你需要确保 , 所有的 variant 都能正常编译

Page 21: Android gradle 从入门到gg 1

android.productFlavors { }现在有免费版和旗舰版了 , 要发应用商店了 , 需要区分各个应用商店的渠道怎么办 ?

flavorDimensions "channel", "type" // flavor 维度声明productFlavors { free { // 免费版本 dimension "type" // type 维度的 free flavor applicationIdSuffix ".free" // 免费版包名后缀 .free } utlra { // 旗舰版本 dimension "type" // type 维度的 ultra flavor applicationIdSuffix ".ultra" // 旗舰版包名后缀 .ultra } flyme { // Flyme 渠道 dimension "channel" // channel 维度的 flyme flavor } tap { // 应用宝 渠道 dimension "channel" // channel 维度的 tap flavor }}

Page 22: Android gradle 从入门到gg 1

android.productFlavors { }

注意 flavorDimensions 后参数的顺序 , 这个顺序就是维度的顺序flavorDimensions "channel", "type" // flavor 维度声明

命令行编译举例 : 编译 flyme 渠道 , 免费版本 , 正式发布包>./gradlew –p app/ assembleFlymeFreeRelease或者偷懒 , 省略每个单词后面的字母也可以>./gradlew –p app/ assFlyFreeRel

后续你还会看到大量驼峰法命名

Page 23: Android gradle 从入门到gg 1

Build Variant

我们现在有 channel 维度 , type 维度 , 以及 buildType 维度 了

打包的时候 , 对每个维度的 sourceSet 的资源选取顺序 , 只要记住前面的覆盖后面的 , 除了 buildType, 优先级最高的是 buildType比如 flymeFreeDebug, debug > flyme > free即 flyme/ 中的同名资源会覆盖 free/ 的 , debug/ 的会覆盖flyme/小技巧 : 永远在后面加上 main 这个默认的基本 sourceSetflymeFreeDebugMain <=> debug > flyme > free > main

Page 24: Android gradle 从入门到gg 1

Build Variant

各个优先级资源覆盖所涉及的 ResourceMerger, ManifestMerger 在后续课程中详细讲解例如 : 高德地图 key 根据编译类型选择 , 不同的渠道包 AndroidManifest 结点数据不一样 , 不同 flavor 的资源不一样 , 代码不一样等等 , 在讲 ResourceMerger, ManifestMerger 的时候详解

Page 25: Android gradle 从入门到gg 1

proguard

proguardFiles, proguardFile 指定 proguard 规则文件 , 建议对引用的第三方 progaurd 文件 , 区分存储所有 开启了混淆 打包的 retrace 文件在 build/outpus/mappings/ 文件夹下

buildTypes { release { minifyEnabled true // 代码混淆 shrinkResources true // 移除没用到的资源和代码 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' progaurdFile "proguard-rxjava.pro" proguardFile "proguard-realm.pro" proguardFile "proguard-retrofit.pro" }}

Page 26: Android gradle 从入门到gg 1

android.sourceSets { }上节课 , 我们已经玩弄过 main source set, 现在我们引入

variantsourceSets { free { // 对 src/free/ source set 进行配置 (flavor) } release { // 对 src/release/ source set 进行配置 (buildType) } freeFlyme { // 对 src/freeFlyme/ 额外 source set 进行配置 }}

我们对 main 可以配置的任何东西 , 都可以对其他 source set 配置freeFlyme { }: 按照之前驼峰法顺序 , 随意截取一段出来 , 都可以这些额外 source set 一般很少用到 , 除非极其针对的业务需求

Page 27: Android gradle 从入门到gg 1

Demo

Demo 实战…

Tuesday, May 2, 2023

刘俊这将是一个系列课程 , 每周一节课

IPD 创新产品部

Page 28: Android gradle 从入门到gg 1

课后任务samples 内有 BasicDSL 工程 , 对免费和旗舰版的 Application Name 后追加 免费版 以及 旗舰版tips: string.xml 文件覆盖http://git.ipd.meizu.com/AnR/android-gradle-samples记得使用自己的邮箱名作为分支名 PR给我[Github 用户移步 ] https://github.com/Jween/android-gradle-samples