Android Studio中的Gradle的相关知识

最近发现自己对Android Studio中的Gradle的相关知识不是很熟悉了(汗),所以特地在周末查了资料重新熟悉了下。

构建工具

软件开发过程不仅仅是编写代码,还涉及到对项目的管理,比如:编译、签名、打包、依赖管理等一系列操作,为了复用以及自动运行这些操作,我们可以用代码来描述这些功能,而构建工具就是可以让我们用代码描述这些功能,并为这些功能性代码的运行提供环境支持的工具。

传统的构建工具有Make、Ant、Maven、Ivy等,而Android Studio中使用的是Gradle,所以接下来我们要对Android Studio中的Gradle的相关配置进行讲解。

Android Studio中Gradle,Gradle插件和BuildTools

Gradle,Gradle插件和BuildTools的区别

Gradle

Gradle是一个基于JVM的构建工具,是一款通用灵活的构建工具,基于Groovy,build脚本使用Groovy编写,在android项目中可以自动帮我们完成项目的依赖,打包,签名,发布等一系列操作。

Gradle插件

Android Gradle Plugin作用是对Android项目提供Gradle构建环境,让开发者可以通过Gradle工具来运行构建。Gradle插件为Gradle的运行提供了环境支持。

BuildTools

Android构建的相关工具都在这里面,位于./sdk/build-tools/目录下,它提供了类似aapt、dx这样的工具,gradle则是使用这样的工具来完成相应的构建任务。

总结来说,Gradle插件为Gradle提供了运行环境,而BuildTools则是Gradle完成操作所需要借助的工具的集合。

指定Gradle的版本

更新Gradle也有两种方式:

  • 通过选择File > Project Structure > Project来指定Gradle版本
  • gradle/wrapper/gradle-wrapper.properties文件中编辑Gradle引用地址

指定Gradle插件的版本

安装Android Studio后就已经帮我安装了Gradle插件.但Gradle插件是独立于Android Studio运行的,所以它的更新也是与Android Studio分开的。

指定Gradle插件版本有两种方式:

  • 在Android Studio中选择File > Project Structure > Project菜单
  • 在顶层build.gradle中修改配置

下面的例子在build.gradle中设置Gradle版本为2.2.0:

1
2
3
4
5
6
buildscript {
...
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
}
}

注意:不应该动态指定版本号,如”com.android.tools.build:gradle:2.+”.这样做可能会导致意外的版本更新,并且会给解决版本差异带来困难。

如果指定的版本没有下载下来,那么项目在下次构建的时候Gradle会再去下载。或者你也可以点击Tools > Android > Sync Project with Gradle Files去下载。

指定BuildTools的版本

app目录下的build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apply plugin: 'com.android.application'

android {
....
buildToolsVersion "25.0.2"
defaultConfig {
....
}
buildTypes {
release {
....
}
}
}

dependencies {
....
}

Gradle,Gradle插件和BuildTools的版本匹配

因为Gradle仍在发展,在不断更新,自然Gradle插件和BuildTools也需要不断更新版本才能提供对新版本Gradle的支持,它们之间存在着版本对应关系。

此处输入图片的描述

Android Studio中的Gradle的配置

设置Gradle的路径

use defalut gradle wrapper

当我们在setting下gradle下设置gradle选择“use defalut gradle wrapper(recommended)”时,as就会根据{project.dir}\gradle\wrapper\gradle-wrapper.properties文件中的配置去查找gradle。

此处输入图片的描述

我们用as构建android项目时,配置gradle时我们必须在{project.dir}\gradle\wrapper\gradle-wrapper.properties文件中配置gradle包。

1
2
3
4
5
6
#Mon Sep 11 14:41:13 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

GRADLE_USER_HOME是我们配置的Gradle所在路径的环境变量。配置的时候可以是“用户主目录/.gradle/wrapper/dists/gradle-..*”或者as安装目录下的gradle目录。

这个配置的gradle如果在目录“用户主目录/.gradle/wrapper/dists/..”存在的话,as就不会去https://services.gradle.org/distributions/gradle-3.3-all.zip去下载了,as就会利用该目录下对应版本的gradle进行相应自动编译操作,如果该目录下不存在gradle的话as就会去站点根据gradle的版本去下载到“用户主目录/.gradle/wrapper/dists/gradle-3.3-all”目录下。

use local gradle distribution

当我们在setting下gradle下设置gradle,如果选择的是“use local gradle distribution”的话,表示用的是本地的gradle,一般情况下本地的gradle目录会选择as的主目录下的gradle目录。这个时候{project.dir}\gradle\wrapper\gradle-wrapper.properties文件中的配置就会失效,也就是说as不会去“用户主目录/.gradle/wrapper/dists/gradle-..*”中去查找gradle。

此处输入图片的描述

Offline work

前面的两个配置是查找构建项目所需要的gradle,而如何Offline work(离线模式)则是和gradle管理依赖有关,选择这个选项,开启离线模式后,Gradle将不会联网查找依赖,而是仅从本地缓存中查找,所以要慎重开启此选项。

补充:

Gradle下载的依赖包的缓存目录

下载的依赖保存在“用户主目录/.gradle/wrapper/dists/gradle-..*”或者as安装目录下的gradle目录。

配置用户环境变量的方法

打开终端输入 open .bash_profile,添加如下内容:

1
2
3
GRADLE_HOME=“用户主目录/.gradle/wrapper/dists/gradle-*.*.*”或者as安装目录下的gradle目录
export GRADLE_HOME
export PATH=$PATH:$GRADLE_HOME/bin

保存退出后,在终端输入:source .bash_profile更新配置。

给Gradle设置代理

Gradle下载依赖的时候,Gradle默认直连网络,即使Mac设置了全局代理也是一样。就算你给Android Studio设置了代理,它依旧会风轻云淡地直连那个你在中国一辈子也不可能连上的网站……

要让Gradle走代理,加快下载依赖包的速度,你需要给它进行单独的配置。

设置全局代理

通过命令行

socks

1
gradle -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=1080 build

http

1
gradle -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8080 build

https

1
gradlew -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=8080 build
通过配置gradle.properties

在.gradle目录中创建gradle.properties文件,.gradle目录默认在用户目录下(区别window/linux),如果你设置了环境变量GRADLE_USER_HOME=“地址”,那么就在这个地址下。

在gradle.properties加入如下内容:

socks

1
2
3
systemProp.socksProxyHost=127.0.0.1
systemProp.socksProxyPort=1080
systemprop.socksProxyVersion=5

http

1
2
systemProp.http.proxyHost=www.somehost.org
systemProp.http.proxyPort=8080

https

1
2
systemProp.https.proxyHost=www.somehost.org
systemProp.https.proxyPort=8080

相同代理协议下,命令行方式中参数-Dxxx的xxx与gradle.properties中systemProp.xxx的xxx是一致的。所以,了解其中一种方式即可,需要时转为另一种方式也很简单

对单个项目设置代理

在项目根目录下gradle.properties 文件中,添加以上内容即可。

Android项目中Gradle相关文件说明

Android Studio中项目的文件目录结构图:

此处输入图片的描述

从上图中我们可以看到,与 Gradle 有关的文件基本上分为七种:

  1. app目录下的build.gradle (当然其他 module 下也有);
  2. 根目录下的gradle 文件夹;
  3. 根目录下的build.gradle ;
  4. 根目录下的settings.gradle ;
  5. 根目录下的gradle.properties ;
  6. 根目录下的local.properties ;
  7. 根目录下的gradlew和gradlew.bat ;

也许有人会说根目录下还有一个config.gradle文件呢,其实这是我自定义的 gradle文件,自定义Gradle文件会在下面中讲解,这里先搁置一下。好了,那么我们一个一个地来看看他们的作用吧。

app目录下的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
apply plugin: 'com.android.application'
android {
compileSdkVersion 23 //编译时候用的sdk的版本
buildToolsVersion "23.0.2" // build工具版本
defaultConfig {
applicationId "com.yuqirong.koku" // 应用包名
minSdkVersion 15 // 最低适用sdk版本
targetSdkVersion 23 // 目标sdk版本
versionCode 1 // 版本号
versionName "1.0" // 版本名称
}
buildTypes {
release {
minifyEnabled true // 开启混淆
zipAlignEnabled true // 对齐zip
shrinkResources false // 删除无用资源
debuggable false // 是否debug
versionNameSuffix "_release" // 版本命名后缀
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 混淆文件
}

debug {
zipAlignEnabled false
shrinkResources false
minifyEnabled false
versionNameSuffix "_debug"
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
}

第一句apply plugin:’com.android.application’主要用来申明这是一个Android程序。而dependencies用于引入依赖,这个相信大家都比较了解了。其他的配置比较简单都有注释,就不展开讲了。

CompileSdkVersion是告诉gradle用哪个SDK版本来编译,和运行时要求的版本号没有关系;使用任何新添加的API就需要使用对应Level的Android SDK。

buildToolsVersion是Android构建工具的版本,其中包括了打包工具aapt、dx等等。这个工具的目录位于..your_sdk_path/build-tools/XX.XX.XX,buildToolsVersion的版本需要>=CompileSdkVersion;高版本的build-tools可以构建低版本的android程序。例如:

1
2
compileSdkVersion 18  
buildToolsVersion "22.0.1"

minSdkVersion最低适用sdk版本,如果compileSdkVersion设置为可用的最新API,那么minSdkVersion则是应用可以运行的最低要求。minSdkVersion是Google Play商店用来判断用户设备是否可以安装某个应用的标志之一。

targetSdkVersion目标sdk版本,targetSdkVersion是Android系统提供前向兼容的主要手段。这是什么意思呢?随着Android系统的升级,某个系统的API或者模块的行为可能会发生改变,但是为了保证老APK的行为还是和以前兼容。只要APK的targetSdkVersion不变,即使这个APK安装在新Android系统上,其行为还是保持老的系统上的行为,这样就保证了系统对老应用的前向兼容性。关于相关的例子和原理,建议阅读:Android targetSdkVersion 原理

minSdkVersion和targetSdkVersion与compileSdkVersion的另一个不同之处是它们会被包含进最终的APK文件中,如果你查看生成的AndroidManifest.xml 文件,你会看到类似下面这样的标签:

1
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="7" />

如果你在manifest文件中手工设置,你会发现Gradle在构建时会忽略它们(尽管其它构建系统可能会明确依赖它们)。

如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion

当然除了上面的配置之外,还有很多配置也常常写入到app/build.gradle 中。我们慢慢往下看。

  • 签名配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
signingConfigs {

release { // 正式版本的签名
storeFile file("../koku.jks") // 密钥文件位置
storePassword "xxxxxxxxx" // 密钥密码
keyAlias "koku" // 密钥别名
keyPassword "xxxxxxxxx" // 别名密码
}

debug { // debug版本的签名
// no keystore
}

}

使用时只要在buildTypes的release中加一句signingConfig signingConfigs.release就好了。

如果你觉得把密钥密码和别名密码放在 app/build.gradle 里不安全,那么可以把相关密码放到不加入版本控制系统的 gradle.properties 文件:

1
2
KEYSTORE_PASSWORD=xxxxxxxxxx
KEY_PASSWORD=xxxxxxxxx

对应的 signingConfigs 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
signingConfigs {
release {
try {
storeFile file("../koku.jks")
storePassword KEYSTORE_PASSWORD
keyAlias "koku"
keyPassword KEY_PASSWORD
}
catch (ex) {
throw new InvalidUserDataException("You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.")
}
}
}
  • Java编译版本配置:
1
2
3
4
compileOptions { // java 版本
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

这里需要注意下,如果Java编译版本为1.8的话,另外在defaultConfig 里要配置Jack编译器:

1
2
3
jackOptions {
enabled true
}
  • Lint检查配置:
1
2
3
lintOptions {
abortOnError false // 是否忽略lint报错
}
  • 多渠道信息配置:
1
2
3
4
5
productFlavors {
xiaomi {}
googleplay {}
wandoujia {}
}

整个app/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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
apply plugin: 'com.android.application'

android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
applicationId "com.yuqirong.koku" // 应用包名
minSdkVersion 15 // 最低适用sdk版本
targetSdkVersion 23 // 目标sdk版本
versionCode 1 // 版本号
versionName "1.0" // 版本名称
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// 默认是umeng的渠道
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "umeng"]
jackOptions {
enabled true
}
}
java 版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
signingConfigs {
release {
storeFile file("../koku.jks")
storePassword "xxxxxx"
keyAlias "koku"
keyPassword "xxxxxx"
}
debug {
// no keystore
}
}
buildTypes {
release {
// 开启混淆
minifyEnabled true
// 对齐zip
zipAlignEnabled true
// 删除无用资源
shrinkResources false
// 是否debug
debuggable false
// 命名后缀
versionNameSuffix "_release"
// 签名
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// 输出apk名称为koku_v1.0_2015-01-15_wandoujia.apk
def fileName = "koku_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}

debug {
zipAlignEnabled false
shrinkResources false
minifyEnabled false
versionNameSuffix "_debug"
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
productFlavors {
xiaomi {}
googleplay {}
wandoujia {}
}
//针对很多渠道
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}

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

def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

再多嘴一句,有了以上的build.gradle配置之后,如果想使用Gradle多渠道打包,需要在AndroidManifest.xml中申明:

1
<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}" />

最后使用命令 gradlew assembleRelease 打包即可。

根目录下的gradle文件夹

gradle文件夹中主要是gradle-wrapper.properties文件比较重要,主要用来声明Gradle目录以及Gradle下载路径等:

1
2
3
4
5
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

里面参数的具体的意义,前面已经讲解过了,这里就不再复述了。

根目录下的build.gradle

根目录下的 build.gradle主要作用就是定义项目中公共属性,比如有依赖的总仓库、Gradle插件的版本等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
jcenter()
mavenCentral()
}
}

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

根目录下的setting.gradle

这个文件是全局的项目配置文件,里面主要声明一些需要加入gradle的module,一些module被主module依赖后,会在这里进行声明。

1
include ':app',':brave'

通过上述的setting.gradle,我们可以知道整个项目中包含了app和brave两个module。

根目录下的gradle.properties

配置gradle运行环境的文件,比如配置gradle运行模式,运行时jvm虚拟机的大小,设置gradle的代理等。

根目录下的local.properties

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

为了安全起见签名文件不可以放在项目中,那么可能每个开发人员的存放地方不同,这种情况下就可以使用local.properties来配置路径然后在app目录下的build.gradle中引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Mon Nov 06 14:20:07 CST 2017
sdk.dir=/Users/baiduo/Library/Android/sdk
#配置keystore文件路径
RELEASE_STORE_FILE=/Users/baiduo/Desktop/Lottery

在build.gradle中引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
signingConfigs {
autoSigning {
#加载properties
def properties = new Properties()
def inputStream = project.rootProject.file('local.properties').newDataInputStream()
properties.load(inputStream)

keyAlias 'IKicker'
keyPassword '*******'
storeFile file(properties.getProperty('RELEASE_STORE_FILE'))
storePassword '*******'
}
}

根目录下的gradlew和gradlew.bat

其实Gradlew只是一个Gradle的封装,是给Unix用户用的。这个脚本的最前面的注释也说明了这个功能:

1
2
3
4
5
6
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################

同样的,gradlew.bat也是一个Gradle的封装,是给Windows用户用的。

1
2
3
4
5
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################

这两个文件的作用就是,任何机器都可以执行gradle构建任务,即使没有装gradle,例如:

1
./gradlew assemble

如果运行时,发现系统没有对应版本的gradle,会通过gradle-wrapper.jar下载gradle-wrapper.properties中指定的gradle版本。这样的话,任何人获取代码后,不用安装gradle,就可以构建工程。

gradle-wrapper.properties文件中指定的版本,就是运行gradle wrapper命令时的gradle版本。
当然,也可以手动指定别的版本,在根目录下build.gradle文件中添加:

1
2
3
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}

再运行gradle wrapper。

这两个文件最重要的运用就是:

  1. 在公司内统一gradle版本
  2. 把gradle-wrapper.properties里面的下载gradle的链接切换到公司的公共空间上,那么下载和安装gradle的时间就可以忽略不计了。

自定义Gradle文件

在上面我们留了一个悬念,就是如何添加我们自定义的Gradle文件。接下来我们就动手来实践一下。在项目根目录下创建文件config.gradle。然后在根目录下的build.gradle开头添加一句apply from: “config.gradle”:

1
2
3
4
5
6
7
8
9
apply from: "config.gradle"

buildscript {
repositories {
jcenter()
}
...
}
...

这句话就代表着把config.gradle添加进来了。然后我们可以在config.gradle中申明一些配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ext {

android = [
compileSdkVersion: 23,
buildToolsVersion: "23.0.3",
applicationId : "com.yuqirong.koku",
minSdkVersion : 14,
targetSdkVersion : 23,
versionCode : 3,
versionName : "1.4"
]

dependencies = [
"appcompat-v7":'com.android.support:appcompat-v7:23.0.1',
"recyclerview-v7":'com.android.support:recyclerview-v7:24.2.1',
"design":'com.android.support:design:23.0.1'
]
}

最后在app/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
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
applicationId rootProject.ext.android.applicationId
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName

jackOptions {
enabled true
}
}
...
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile rootProject.ext.dependencies["appcompat-v7"]
compile rootProject.ext.dependencies["recyclerview-v7"]
compile rootProject.ext.dependencies["design"]
}

从上面可以看到,我们把一些固定的配置“拎”出来放到config.gradle 中,这样以后直接更改config.gradle就行了,方便多人协作开发。

Android Studio中的Gradle工具窗口

可以通过View->Tool windows->Gradle打开,也可以从右侧纵向标签页点击打开。

此处输入图片的描述

参考链接

Android Gradle和Gradle插件区别
Gradle构建工具与Android对应关系

AndroidStudio gradle配置
Mac下AndroidStudio中手动配置Gradle

IDEA及Gradle使用总结
Gradle中文教程系列-跟我学Gradle-14.1:IDEA中Gradle插件的使用

gradle设置代理
Gradle 设置代理

关于Gradle配置的小结

给ANDROID 初学者的GRADLE知识普及
ANDROID 开发你需要了解的GRADLE配置

关于Android Studio里的Gradle,你所需要知道的都在这里了

AndroidStudio gradle安装配置详解-透过现象看本质

Android local.properties配置文件的使用

使用Gradle构建Android程序(再仔细看看)
请问android studio创建的工程目录下的gradlew文件有什么作用?gradlew 和 gradle 有什么区别?

《Android群英传:神兵利器》—-Gradle章节

Gradle 完整指南(Android) //待读
Android Studio中Gradle使用详解 //待读
Android studio Gradle的介绍和部分问题小结//待读
Android Studio中Gradle使用详解//待读
Android中Gradle详细实用指南//待读
Android Studio Gradle使用笔记//待读


Gradle Android插件用户指南翻译
Android Plugin DSL Reference


深入理解Android(一):Gradle详解
Groovy Tip 12 Range的用法
Groovy基础——Closure(闭包)详解


Gradle User Guide
AndroidStudio配置构建
Android Plugin DSL Reference
Gradle-中文用户组一款简洁而优雅的构建工具


Gradle全局变量设置、自定义BuildConfig
Gradle配置全局变量

利用 Android Studio 和 Gradle 打包多版本APK( applicationIdSuffix)

Gradle自定义插件


Android 7.0 Nougat 无法安装渠道包问题


application android:debuggable=”false” 有什么用?


android lint选项含义
Gradle lint 配置


解决AndroidStudio导入项目在 Building gradle project info 一直卡住


加速Android Studio/Gradle构建
加快gradle的编译速度总结-亲身经历


解决传说中的 Android 65k 问题
Android Studio 错误 Duplicate files copied in APK META-INF/LICENSE.txt
Duplicate files copied in APK META-INF/license.txt


NDK SO 库开发与使用中的 ABI 构架选择
studio android.useDeprecatedNdk=true解决ndk提示版本低不能自动编译jni


当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器