Android Studio之project/module/settings gradle

1、gradle是什么:

Gradle是一个基于JVM的构建工具,是一款通用灵活的构建工具,支持maven, Ivy仓库,支持传递性依赖管理,而不需要远程仓库或者是pom.xml和ivy.xml配置文件,基于Groovy,build脚本使用Groovy编写。

2、android项目中的gradle文件:

通常一个android项目会有project、module、settings这三个gradle文件,如下图:
Android项目gradle文件.png
3、Project gradle文件:

首先我们看一下Project gradle文件:

// Gradle中可以使用“//”或“/**/”来添加注释,与Java类似。
// 根目录下的build.gradle用于添加子工程或模块共用的配置项。

// "buildscript"的类型为script block,而且是最上层的script block,用于配置Gradle的Project实例。其API文档为https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:buildscript(groovy.lang.Closure)
// 其余的根script block有"allprojects", "dependencies", "configurations"等,更多的可见https://docs.gradle.org/current/dsl/的“Build script structure”一节。
// Script Block是一种method的调用,传入的参数为configuration closure。执行后会对Project的属性进行配置。
// 此处的"buildscript"用于配置Project的build script的classpath。
buildscript {
    ext.kotlin_version = '1.1.2-4'
    repositories {
        // 从https://maven.google.com下载code reposities 同google()
        maven { url 'https://maven.google.com' }
        // 从https://jcenter.bintray.com/下载code reposities。
        jcenter()
        // 从https://dl.google.com/dl/android/maven2/下载code reposities
        google()
    }
    // 定义classpath,gradle会从“repositories”中下载对应版本的Gradle。如果使用gradle wrapper的话,感觉这个配置会被忽略。Wrapper会自己去下载所使用的gradle版本。
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
// 该配置会被应用到所有的子工程。
allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
        maven { url "https://jitpack.io" }
        mavenCentral()
    }
}
// 运行gradle clean时,执行此处定义的task。
// 该任务继承自Delete,删除根目录中的build目录。
// 相当于执行Delete.delete(rootProject.buildDir)。
// gradle使用groovy语言,调用method时可以不用加()。
task clean(type: Delete) {
    delete rootProject.buildDir
}

这里首先要注意到buildscript与allprojects中都有repositories,他们的作用分别是什么?buildscript里是gradle脚本执行所需依赖,分别是对应的maven库和插件,如果把里面的库都注释掉,你会发现下面的gradle:3.0.1版本和kotlin都没办法使用了。allprojects里是项目本身需要的依赖,如果你把这里的库注释掉,你会发现module project里面的依赖都无法使用了。
  下面接着说buildscript里面的repositories中的库,maven { url 'https://maven.google.com' },这里它的作用其实是跟google()的功能是一样的,都指向的google的maven库,google()可以视作是它的快捷方式,google()是在Gradle4.x中引入的,国内无法访问https://maven.google.com,但是可以使用其替代库https://dl.google.com/dl/android/maven2/也即google(),另外使用google()的条件是:Android3.0及以上版本,Gragdle4.0及以上版本。jcenter()是一个由bintray.com维护的Maven仓库(这里是仓库的内容:https://oss.sonatype.org/content/repositories/releases/。在早期的android studio的版本中,还使用了mavenCenter()插件库,但是后来被去掉了,这是因为jecenter相比于mavenCenter在以下几个方面更有优势:1、在性能和占存储大小方面比mavenCenter()更优。2、jcenter通过CDN发送library,开发者可以享受到更快的下载体验。3、jcenter是全世界最大的Java仓库,因此在Maven Central 上有的,在jcenter上也极有可能有。换句话说jcenter是Maven Central的超集。4、上传library到仓库很简单,不需要像在 Maven Central上做很多复杂的事情。一般情况下我们在新建一个项目的时候jecenter()、google()会自动的添加到项目中,除了这两个标准的library以外我们还可以使用其他的或自定义的maven库,这时候就需要我们在项目中自己申明了,比如:maven { url "https://jitpack.io" }。

4、Module gradle文件:

这里展示一个demo gradle文件

//指明这是一个类库,这里指明这是一个android工程,也可以填com.android.library
apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

android {
    //使用的编译版本SDK28
    compileSdkVersion 28
    //buildtool版本 指定为28.0.3
    buildToolsVersion "28.0.3"
    defaultConfig {
        applicationId "com.saicfinance.androiddemo"
        //最小SDK18
        minSdkVersion 18
        //目标版本(也即程序运行时版本)28
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    // 打包签名
    signingConfigs {
        //指定debug模式下使用的签名文件
        debug { storeFile file("debug.keystore") }
        release {
            //发布正式版本模式下的使用的签名文件
            storeFile file('release.keystore')
            storePassword 'thisiskeystorepassword'
            keyAlias 'nim_demo'
            keyPassword 'thisiskeypassword'
        }
    }
    //编译时脚本运行环境
    buildTypes {
        // debug环境配置
        debug {
            // 指定签名为debug
            signingConfig signingConfigs.debug
            // 设置使用第三方sdk注册文件在debug环境下的配置key
            manifestPlaceholders = [AMAP_KEY: "09fd4efd3e28e9bf1f449ecec7d34bfe"]
        }
        //正式版本环境配置
        release {
            // 是否混淆  
            minifyEnabled true
            // 是否zip优化
            zipAlignEnabled true
            // 删除无效的文件
            shrinkResources true
            // 设置混淆文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // 指定签名为release
            signingConfig signingConfigs.release
            // 设置使用第三方sdk注册文件在release环境下的配置key
            manifestPlaceholders = [AMAP_KEY: "ee20324fba1c7f4ad7a4a207e7f08e8d"]
        }
    }
}
// module项目依赖
dependencies {
    //依赖文件夹下的所有文件
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}

上面就是一个基本的gradle文件的一些配置,当然根据项目的情况不同,可能还需要加一些别的配置,这里就暂时不介绍了。下面介绍一些比较基础的知识:
1)compileSdkVersion、targetSdkVersion、minSdkVersion作用和如何选择关系。

compileSdkVersion这个主要是我们编译app时候用的sdk版本,就我们在AndroidStudio上面点击运行时候的编译时候的环境。记住这个只是在编译时候选择的版本,不涉及到运行时候的行为。由于androidStudio有预编译的功能所以会提示一些警告,提前了解新的sdk api。修改compileSdkVersion并不会影响我们的我们生成的app在手机上运行的行为。例如在android6.0之前的系统是不需要动态申请权限的,在6.0之后的系统需要动态申请权限。这个和你的compileSdkVersion的版本选择是完全没有任何关系的。也就是说你app运行时需不需要动态申请权限和你complieSdk是否设置的6.0,没有半毛钱关系,记住compileSDK只是关系到你编译出来的包。不是运行的表现行为。所以修改compileSdkVersion是不会改变你app在手机上运行的表现行为的。但是我们一般情况,也是最理想的情况就是把compileSdkVersion设置到最高,因为使用新的编译检查可以获得很多好处,可以避免弃用的API,并且为使用新的API做好准备。

targetSdkVersion:这个是程序运行时指定的sdk版本,比如Android 9.0系统就对应这sdk 28,如果设置了targetSdkVersion=28,那么程序运行的表现形式就要按照android 9.0的系统来,比如动态请求权限在sdk 23的时候有了,但是22的时候并没有,这时候如果你设置的targetSdkVersion=22,那么程序在运行的时候并不会动态请求权限。它的作用主要有三个:1.提供向下兼容。2.确定app的表现行为。3.这允许你在适应新的行为变化之前就可以使用新的 API。

minSdkVersion:这个就是程序运行的最低的要求的Sdk,就是给说如果我设置的minSdkVersion是15的话那么如果你系统低于这个SdkVersion是安装不上的。还有一个好处就是。例如你设置miniSdk是3.0的话,你写的方法只有在4.0后才有的方法,这个时候就会提示你在3.0的时候是没有这个方法的。

总的来说,我们项目中设置这三个属性的值的时候要这样来设置:minSdkVersion<=targetSdkVersion<=compileSdkVersion

2)buildToolsVersion和sdkVesion之间的关系。

android构建工具的版本,在SDK Manager中安装选择版本,buildToolsVersion的版本需要>=CompileSdkVersion; 高版本的build-tools 可以构建低版本编译的android程序;

3)manifestPlaceholders配置是干嘛的?配置了有什么好处?

manifestPlaceholders 可以替换androidmanifest文件中的标签,可作为快速渠道打包/多渠道打包(结合productFlavors)替换渠道名的一种方式,也可以自定义标签用来替换需要的文本,多作为不同环境不同key的修改。

那在这里配置相比于在注册文件中配置有什么优势呢?可能你已经注意到了在上面的demo gradle文件中我们配置了debug与release的key,这在注册文件中是做不到的。点开的源码它接受的参数是一个map:

public void setManifestPlaceholders(Map<String, Object> manifestPlaceholders) {
     this.mManifestPlaceholders.clear();
     this.mManifestPlaceholders.putAll(manifestPlaceholders);
}

4)buildTypes中关于文件混淆设置。
详细请参考我的另外一篇文章:文件混淆

5)dependencies{}中的“implementation”
在android studio 3.0之前引入库的时候你可以这样写:

compile 'com.android.support:appcompat-v7:28.0.0'

在3.0之后增加了implementation,它们的作用相同都是引入库,区别在于如果模块之间有依赖关系的话,compile引入的库在模块之间是可以使用的,而implementation引入的库只能在当前模块中使用。例如,项目中有一个common module,如果Amodule依赖于common,那么common mudule中的依赖可以用“compile”,这样A模块中就可以直接引用这些依赖了。

4、Settings gradle文件:

Setting文件主要是为了引入子项目(Module)
include ':demo1app', ':demo2app'
Android Studio可以在一个工程(project)下管理多个module,一个project下只会有一个settings文件,其他的module需要在settings.gradle文件中引入。

5、gradle-wrapper.properties文件:

gradle-warpper.properties主要用来制定当前使用的gradle版本从哪里获取。以及一些其他的参数。
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

6、gradle.properties文件:

这个文件可用来配置全局键值对数据的,你在这个文件中设置的key值,可以直接在build.gradle文件中直接访问到。

下面是一般项目中可能会配置的信息:

# 指定守护进程的JVM参数
org.gradle.jvmargs=-Xmx1536m

# 设置代理
systemProp.http.proxyHost=10.116.x.xx
systemProp.http.proxyPort=80
systemProp.https.proxyHost=10.116.x.xx
systemProp.https.proxyPort=80

jvmargs:指定守护进程的JVM参数,这个设置对于调整内存设置特别有用,可以用来加快gradle的编译。
下面的是配置项目代理信息,一般在公司开发项目的时候,公司的网络都需要通过代理上网,那么你项目中就需要设置网络的代理信息。

7、local.properties文件:

文件在Android Studio中是用来配置SDK目录的,也可以在文件中配置一些本地化的变量。这个文件不会被提交到版本控制中。

如果你想上传你的项目到github上,但是又怕一些隐私配置(比如打包信息)被泄露,你可以把隐私信息配置到local.properties文件中,然后在build.gradle文件中设置这些配置,如下:

sdk.dir=/Users/weicz/Library/Android/sdk
#配置keystore文件参数
KEY_ALIAS = demo
KEY_PASSWORD = thisiskeypassword
STORE_PASSWORD = thisiskeystorepassword
STORE_FILE_PATH = yourstorefilepath

然后在你的build.gradle文件中你可以这样使用:

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            storeFile file(properties.getProperties('STORE_FILE_PATH'))
            storePassword file(properties.getProperties('STORE_PASSWORD'))
            keyAlias file(properties.getProperties('KEY_ALIAS'))
            keyPassword file(properties.getProperties('KEY_PASSWORD'))
        }
    }

文章参考:
Android Studio之maven Central,JCenter
compileSdkVersion,minSdkVersion,targetSdkVersion 的区别和比较
Android Gradle manifestPlaceholders 的妙用

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容