gradle

作者: 池鹏程 | 来源:发表于2018-11-29 09:20 被阅读0次

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加入对应语句,结果却报错。 20180309171200884.png

我在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版本的依赖方式

2.0.png

3.0的 old.png

可以看到在Android studio3.0中,
compile依赖关系已被弃用,被implementation和api替代,
provided被compile only替代,apk被runtime only替代。

implementation和api的区别:

api:跟 2.x 版本的 compile完全相同

implementation:使用了该命令编译的依赖,它仅仅对当前的Module提供接口。例如我们当前项目结构如下 newOr.png
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.supportgson这些使用者常用的库,避免冲突。


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 指令

相关文章

网友评论

      本文标题:gradle

      本文链接:https://www.haomeiwen.com/subject/qvkxcqtx.html