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的
可以看到在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 指令