Android开发中常用Gradle配置
该博客是我在使用Android Gradle过程中遇到的问题和学习汇总,博客中的内容主要是参考其他博客。所参考博客的地址都写在参考一节了。
1. Gradle文件结构
对于一个gradle 项目,最基础的文件配置如下:
一个项目有一个setting.gradle、包括一个顶层的 build.gradle文件、每个Module (如app)都有自己的一个build.gradle文件。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
allprojects{
repositories{
jcenter()
}
}
其中:
- buildscript:定义了 Android 编译工具的类路径。repositories中,jcenter是一个著Maven 仓库;
- allprojects:中定义的属性会被应用到所有 moudle 中,但是为了保证每个项目的独立性,我们一般不会在这里面操作太多共有的东西。
其中:
- apply plugin:第一行代码应用了Android 程序的gradle插件,作为Android 的应用程序,这一步是必须的,因为plugin中提供了Android 编译、测试、打包等等的所有task。
- android:这是编译文件中最大的代码块,关于android 的所有特殊配置都在这里,这就是我们前面的声明的 plugin 提供的。
- defaultConfig:程序的默认配置,注意,如果在AndroidMainfest.xml里面定义了与这里相同的属性,会以这里的为主。
注意:applicationId的选项:在我们曾经定义的AndroidManifest.xml中,那里定义的包名有两个用途:一个是作为程序的唯一识别ID,防止在同一手机装两个一样的程序;另一个就是作为我们R资源类的包名。在以前我们修改这个ID会导致所有用引用R资源类的地方都要修改。但是现在我们如果修改applicationId只会修改当前程序的ID,而不会去修改源码中资源文件的引用。 - buildTypes:定义了编译类型,针对每个类型我们可以有不同的编译配置,不同的编译配置对应的有不同的编译命令。默认的有debug、release 的类型。
- dependencies:是属于gradle 的依赖配置。它定义了当前项目需要依赖的其他库。
2. AAR引用
协作开发中引用AAR是比较正常的事情,这一条属于基本技能。引用也是十分简单的,直接把aar文件放到libs目录下,然后在gradle下面配置一行:
repositories{
flatDir{
dirs 'libs'
}
}
注意:外层的repositories不能少,然后直接就可以在dependencies中添加引用,注意单引号
compile(name: 'widget2-debug', ext: 'aar')
3. 自动生成versionCode,versionName
直接依靠gradle的语法来实现版本号的修改,分离主版本子版本,根据自己的逻辑进行修改。
def versionMajor = 2
def versionMinor = 1
def versionPatch = 0
android {
...
defaultConfig {
...
versionCode versionMajor * 100 + versionMinor * 10 + versionPatch
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
}
}
4. 配置release和debug的applicationId
使用applicationidsuffix可以为debug版本添加一个后缀到你的applicationid上。这个小技巧可以让我们在同一台设备上安装多个版本的apk,不用频繁卸载。
buildTypes {
debug {
applicationIdSuffix ".debug"
}
...
}
5. 保持依赖版本同步
在现在越来越大的项目中,各种Module,子Module,引用版本不一致导致经常需要同步下载,而且一旦想要升级插件,support包之类的,可能有好多个需要同时升级。使用Gradle,我们也能做到这一点。首先在最外层的根build.gradle中,在ext块内定义一个版本
ext {
supportLibVer = "24.2.1"
}
这样我们就能在需要的地方引用了
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibVer"
compile "com.android.support:design:$rootProject.ext.supportLibVer"
...
}
包版本可以这么玩,其他的所有配置其实都可以这么玩,我们可以把配置抽成一个单独的gradle文件,里面就一个ext block。
ext {
androidPluginVer = "2.1.3"
compileSdkVer = 24
buildToolsVer = "24.0.2"
minSdkVer = 14
targetSdkVer = 24
supportLibVer = "24.2.1"
}
我们把这个命名成config.gradle,然后要做的就是让子module都能引用到这个,简单的做法就是直接让刚才的root gradle文件引用这个gradle配置文件。
这里有一点坑就是看你自己创建的gradle目录在哪一级,需要定位到才能找得到 不然会出错,这里我是在最外层,所以加了两处,另外改ext属性,需要手动同步一下,直接跑的话并不会自动同步,这是最关键的一点。
buildscript {
apply from: 'config.gradle'
...
}
subprojects {
apply from: '../config.gradle'
}
使用的话和前面的ext属性差不多,加不加rootProject都可以跑得动
6. 编译成library
如果我们要将一个module编译成library让其他的项目引用,我们需要在该module的bubild.gradle中将plugin设置为如下plugin:
apply plugin: 'com.android.library'
7. 优化编译速度
可以通过以下方式加快gradle 的编译:
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m
引用的时候在setting文件中include即可。
8. 自动优化无用的资源
在编译的时候,我们可能会有很多资源并没有用到,此时就可以通过shrinkResources来优化我们的资源文件,除去那些不必要的资源。
某些情况下,一些资源是需要通过动态加载的方式载入的,这时候我也需要像 Progard 一样对我们的资源进行keep操作。方法就是在res/raw/下建立一个keep.xml文件,通过如下方式 keep 资源:
9. Gradle依赖配置compile,implementation和api的区别
Gradle3.4之前的版本使用如下方式添加依赖:
dependencies {
compile 'commons-httpclient:commons-httpclient:3.1'
compile 'org.apache.commons:commons-lang3:3.5'
}
Gradle 3.4+后使用如下方式添加依赖:
dependencies {
api 'commons-httpclient:commons-httpclient:3.1'
implementation 'org.apache.commons:commons-lang3:3.5'
}
其中api和implementation两种依赖的不同点在于:它们声明的依赖其他模块是否能使用。
- api:当其他模块依赖于此模块时,此模块使用api声明的依赖包是可以被其他模块使用
- implementation:当其他模块依赖此模块时,此模块使用implementation声明的依赖包只限于模块内部使用,不允许其他模块使用。
10. FAQ
10.1 Gradle sync failed: ‘xxx’ already disposed:
错误特征:
14:37 Gradle sync started
14:37 Gradle sync failed: 'shadows-core-3.0' already disposed:
14:37 Gradle sync completed
14:39 Gradle sync started
14:39 Gradle sync failed: 'robolectric-resources-3.0' already disposed:
14:40 Gradle sync completed
解决方法:
./gradlew clean
Restart Android stduio
10.2 调试时出现“line number info is not available”
编译debug版本时打开了混淆开关,按如下方式修改:
buildTypes {
debug {
testCoverageEnabled = true
debuggable true
minifyEnabled false //值改为false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
......
}
参考
- Android开发中那些常用的Gradle配置. https://www.jianshu.com/p/d412e04ab38d
- Android Gradle 完整指南. https://www.cnblogs.com/laughingQing/p/5855774.html
- https://www.jianshu.com/p/1eac2ecacf88