settings.gradle
Setting文件可以说是子项目(也可以说是Module)的配置文件,大多数setting.gradle的作用是为了配置子工程,再Gradle多工程是通过工程树表示的,如在Android studio中我们指定相应的module能在主工程当中使用,需要这样
include ':example'
正常情况下,你对着一个module,点击右键,它是不会有delete这个选项的。你要是在settings.gradle那里去掉了,在对着那个module那里点右键,就会出来delete了。所以,那个settings.gradle,他的作用大概就是告诉AS,这个项目里面有哪些Module,如果里面没有写到的,AS就找不到了。
今天楼主碰到一个添加module的问题,把module拷贝到对应文件里,然后在build.gradle加入对应语句,结果却报错。
我在settings.gradle文件里加入对应的module就可以使用了
根目录-build.gradle
// Gradle中可以使用“//”或“/**/”来添加注释,与Java类似。
// 根目录下的build.gradle用于添加子工程或模块共用的配置项。
// 此处的"buildscript"用于配置Project的build script的classpath。
//-------------配置工程的仓库地址---------
buildscript {
//如果需要的话,从https://jcenter.bintray.com/下载code reposities。
repositories {
jcenter()
}
// 定义classpath,gradle会从“repositories”中下载对应版本的Gradle。如果使用gradle wrapper的话,感觉这个配置会被忽略。Wrapper会自己去下载所使用的gradle版本。
//-------------------------配置工程的"插件"依赖地址(即gradle程序的第三库)-------------------------
dependencies {
//ependencies闭包中使用classpath声明了一个Gradle插件。为什么要声明这个插件呢?因为Gradle并不是专门为构建Android项目而开发的,java,c++等很多项目都可以使用Gradle来构建。因此如果我们要想使用它来构建Android项目,则需要声明com.android.tools.build:gradle:2.2.2这个插件。
classpath 'com.android.tools.build:gradle:2.2.2'
}
}
// 该配置会被应用到所有的子工程。
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
// 运行gradle clean时,执行此处定义的task。
// 该任务继承自Delete,删除根目录中的build目录。
// 相当于执行Delete.delete(rootProject.buildDir)。
// gradle使用groovy语言,调用method时可以不用加()。
task clean(type: Delete) {
delete rootProject.buildDir
}
//两处repositories的闭包中都声明了jcenter()进行配置,那么这个jcenter是什么意思呢?
//其实它是一个代码托管仓库,很多Android开源项目都会选择将代码托管到jcenter上,
//声明了这行配置之后,我们就可以在项目中轻松引用任何jcenter上的开源项目了。
app目录下的的build.gradle
//第一行应用了一个插件,一般有两种值可选:com.android.application表示这是一个应用程序模块,com.android.library表示这是一个库模块。
//应用程序模块和库模块的最大区别在于,
//一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行。
apply plugin: 'com.android.application'
android {
//compileSdkVersion用于指定项目的编译版本
compileSdkVersion 23
//buildToolsVersion 用于指定项目构建工具的版本
buildToolsVersion "23.0.3"
//这里在android闭包中又嵌套了一个defaultConfig闭包,defaultConfig闭包中可以对项目的更多细节进行配置
defaultConfig {
//applicationId 用于指定项目的包名,前面我们在创建项目的时候其实已经指定过包名了,如果你想在后面对其进行修改,那么就是在这里修改的
applicationId "com.example.helloworld"
//用于指定项目最低兼容的Android系统版本
minSdkVersion 15
//指定的值表示你在该目标版本上已经做过了充分的测试,系统将会为你的应用程序启用一些最新的功能和特性。
//比如说Android 6.0系统中引入了运行时权限这个功能。而如果你将targetSdkVersion 指定成22,
//那么就说明你的程序最高只在Android 5.1系统上做过充分的测试,Android 6.0系统中引入的新功能自然就不会启用了。
targetSdkVersion 23
//versionCode用于指定项目的版本号,versionName用于指定项目的版本名
//这两个属性在生成安装文件的时候非常重要。
//用于指定项目的版本号
versionCode 1
//用于指定项目的版本名
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
//buildTypes闭包中用于指定生成安装文件的相关配置,通常只会有两个子闭包,一个是debug,一个是release。
//debug闭包用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。
//debug闭包是可以忽略不写的,因此我们看到上面的代码中就只有一个release闭包。
buildTypes {
release {
//minifyEnabled用于指定是否对项目的代码进行混淆,true 表示混淆,false 表示不混淆。
minifyEnabled false
//proguardFiles 用于指定混淆时使用的规则文件,这里指定了两个文件
//第一个proguard-android.,txt 是在Android SDK目录下的,里面是所有项目通用的混淆规则
//第二个 proguard-rules.pro 是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
//这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。
//通常AndroidStudio项目一共有3种依赖方式:本地依赖、库依赖和远程依赖。
//本地依赖可以对本地的jar包或目录添加依赖关系,
//库依赖可以对项目中的库模块添加依赖关系,
//远程依赖则可以对jcenter库上的开源项目添加依赖关系。
dependencies {
//compile fileTree就是一个本地依赖声明,它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
//compile 则是远程依赖声明,
//com.android.support:appcompat-v7:23.4.0就是一个标准的远程依赖库格式,
//其中com.android.support是域名部分,用于和其他公司的库做区分;
//appcompat-v7是组名称,用于和同一个公司中不同的库做区分;
//23.4.0是版本号,用于和同一个库不同的版本做区分。
//加上这句声明后,Gradle在构建项目时会首先检查一个本地是否已经有这个库的缓存,如果没有的话则会去自动联网下载,然后再添加到项目的构建路径当中。
//至于库依赖声明这里没有用到,它的基本格式是compile project后面加上要依赖的库名称,
//比如说有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加入compile project(':helper')这句声明即可。
compile 'com.android.support:appcompat-v7:23.4.0'
testCompile 'junit:junit:4.12'
}
android gradle依赖:implementation 和compile的区别
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
首先是2.x版本的依赖方式

3.0的
old.png

可以看到在Android studio3.0中,
compile依赖关系已被弃用,被implementation和api替代,
provided被compile only替代,apk被runtime only替代。
implementation和api的区别:
api:跟 2.x 版本的 compile完全相同

LibraryA 中引用了 LibraryC 的库,如果对 LibraryC 的依赖用的是 implementation 关键字。 如下:
dependencies {
. . . .
implementation project(path:':libraryC')
}
那么LibraryC 中的接口,仅仅只能给 LibraryA 使用,而我们的 App Module 是无法访问到 LibraryC 提供的接口的,也就是将该依赖隐藏在内部,而不对外部公开。这就是implementation关键字的作用。
建议
在Google IO 相关话题的中提到了一个建议,就是依赖首先应该设置为implement的,如果没有错,那就用implement,如果有错,那么使用api指令,这样会使编译速度有所增快。
那为什么要这么做呢?
答案是: 1. 加快编译速度。2. 隐藏对外不必要的接口。
为什么能加快编译速度呢?
这对于大型项目含有多个Module模块的, 以上图为例,比如我们改动 LibraryC 接口的相关代码,这时候编译只需要单独编译LibraryA模块就行, 如果使用的是api或者旧时代的compile,由于App Module 也可以访问到 LibraryC,所以 App Module部分也需要重新编译。当然这是在全编的情况下。
compile(api)
这种是我们最常用的方式,使用该方式依赖的库将会参与编译和打包。
当我们依赖一些第三方的库时,可能会遇到com.android.support冲突的问题,就是因为开发者使用的compile依赖的com.android.support包,而他所依赖的包与我们本地所依赖的com.android.support包版本不一样,所以就会报All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes这个错误。
解决办法可以看这篇博客:com.android.support冲突的解决办法
provided(compileOnly)
//场景:1如果主工程已经有某库了, 他的库工程也需要引入该库,可用provided
//2比如热更新,只需编译时生成某些库,打包不需要该库,那也可以
只在编译时有效,不会参与打包
可以在自己的module中使用该方式依赖一些比如com.android.support,gson这些使用者常用的库,避免冲突。
apk(runtimeOnly)
只在生成apk的时候参与打包,编译时不会参与,很少用。
testCompile(testImplementation)
testCompile 只在单元测试代码的编译以及最终打包测试apk时有效。
debugCompile(debugImplementation)
debugCompile 只在 debug 模式的编译和最终的 debug apk 打包时有效
releaseCompile(releaseImplementation)
Release compile仅仅针对 Release 模式的编译和最终的 Release apk 打包。
参考链接:
Android Studio3.x新的依赖方式(implementation、api、compileOnly)
还再用compile依赖?那你就落后啦
android gradle tools 3.X 中依赖,implement、api 指令