第三章 依赖管理

第三章 依赖管理

我们只需要在构建文件 build.gradle 中添加一行代码,Gradle 将会从远程仓库下载依赖,确保我们的项目能够使用依赖中的类。

  • 如果我们的项目中的某一个依赖A,A自己还有一个依赖B,Gradle 会帮助我们处理这种情况,这些依赖中的依赖叫做 依赖传递

一、依赖仓库

一般情况下我们讨论的依赖指的是外部依赖,比如其他开发者提供的 依赖库
一个 依赖仓库 可以被看做是文件的集合。Gradle 默认情况下不会给我们的项目添加任何依赖,我们需要在 repositories 代码块中添加它们。

repositories{
    jcenter()
}

Gradle 支持三种不同的依赖仓库:Maven Ivy 静态文件或文件夹。在构建的执行阶段,依赖从依赖仓库中被获取出来。Gradle 也有本地缓存,所以一个特定版本的依赖只会下载一次。
一个依赖通常由三种元素定义:group name version

  • group:指定了创建该依赖的组织,通常是反向域名(可选,为了表述清楚一般会添加group)
  • name:依赖库的唯一标识 (必选)
  • version:指定了需要使用依赖库的版本(可选,不写的话依赖会自动更新,可能会影响到项目构建)
image

1. 预定义依赖仓库

为了方便,Gradle 预定义了三个 Maven 仓库:JCenter Maven Central 本地Maven仓库
repositories 中添加他们:

repositories {
    jcenter()
    mavenCentral()
    mavenLocal()
}

默认情况下,使用 AndroidStudio 创建 Android 项目时,默认使用的依赖仓库就是 JCenterJCenterMaven Central 的超集,并且 JCenter 支持 HTTPS

2. 远程仓库

一些组织会创建有趣的插件或依赖库,并且更喜欢将它们放在自有的 MavenIvy 服务器上,而不是将它们发布到 Maven CentralJCenter。如果要想在构建中使用这些依赖,需要在 maven 代码块中添加 URL

image

如果你的团队正在使用自己的仓库,那么需要进行资格验证后才能访问它们,下面是为一个仓库添加凭证的方法:

maven {
    url "http://repo.example.com/maven2"
    //验证
    credentials{
        //用户名
        username 'user'
        //密码
        password 'secretpassword'
    }
}
  • 不建议在构建配置文件中存储你的凭证。更高的方法是使用一个单独的 Gradle 属性文件
  • 因为配置文件会被迁入源码控制系统。

3. 本地仓库

我们可以在自己的硬盘驱动器或网络驱动器上运行 MavenIvy 仓库。要想在构建中添加本地仓库,只需要配置一个相对或绝对路径的 URL 即可:

repositories{
    maven{
        url "../repo"
    }
}

新的 Android 项目默认情况下有一个 Android Support Library
的依赖。当使用 SDK Manager 来安装 Google 仓库时,在硬件驱动器上,会创建两个 Maven 仓库,分别是 ANDROID_SDK/extras/google/m2repositoryANDROID_SDK/extras/android/m2repositoryGradle 通过它们获取谷歌提供的依赖包(eg:Android Support LibraryGoogle Play Services

二、本地依赖

有时我们可能需要创建自己的依赖库,以便可以在没有将其发布到公有或私有仓库时在多个项目中复用。这时,我们不能使用任何在线资源,必须通过其他方式来添加依赖。

1. 文件依赖

可以使用 Gradle 提供的 files 方法来添加 JAR 文件作为一个依赖:

dependencies{
    implementation files('libs/xxx.jar')
}

也可以直接添加一个完整的文件夹:

dependencies{
    //会直接把 libs 下的 文件 包全部引用
    implementation fileTree('libs')
}

默认情况下,新建的 Android 项目会有一个 libs 文件夹,其会被声明为依赖使用的文件夹,默认情况下会依赖 libs 文件夹下的所有文件。可以使用过滤器来选定只依赖 JAR 文件:

dependencies{
    //会直接把 libs 下的 Jar 包全部引用
    implementation fileTree(dir: 'libs', include:['*.jar'])
}

2. 原生依赖库

CC++ 编写的依赖库可以被编译成特定平台的原生代码。这些依赖库通常包含几个 .so 文件,可以用于所有平台。 Android 插件默认支持原生依赖库(用 CC++ 编写的),我们只需要在模块层创建一个 jniLibs 文件夹,然后为每个平台创建子文件夹,将 .so 文件放在适当的文件夹中:

image

image

armeabi,armeabi-v7a问题等是什么的问题

image

3. 依赖项目

如果想自己写一个 Android APIAndroid 资源 的依赖库分享给别人使用,那么需要创建一个依赖项目。依赖项目通常和应用项目类似,不同之处在于输出不同。应用项目将生成一个可被安装和运行在 Android 设备上的 APK ,依赖项目则生成一个 .aar 文件。该文件可被 Android 应用项目用作依赖库。

1) 创建和使用依赖项目模块

不同于 Android 应用插件,构建脚本需要应用 Android 依赖库插件:
apply plugin: 'com.android.library'

在应用中包含依赖项目的方式有两种:
在项目中当做一个模块 创建一个可在多个应用中复用的 .aar 文件

如果在项目中创建了一个模块作为依赖项目,那么我们需要在 setting.gradle 中添加该模块,在应用模块中将它作为依赖:
Include ':app', ':library'

在这种情况下,依赖模块被称为依赖库,并且文件夹的名称与此相同,要在 Android 模块中使用依赖库,需要在 Android 模块的 build.gradle 文件中添加一个依赖库:

dependencies{
    compile project(':library')
}

跳转到第五章查看详细方法

2)使用 .arr 文件

如果创建了一个依赖库,想在不同的 Android 应用中复用,那么可以创建一个 .aar 文件,然后将其作为一个依赖添加到项目中。在构建依赖库时,模块目录下的 build/out/aar/ 文件夹将会生成 .aar 文件。在应用模块中创建一个文件夹,赋值 .aar 文件到该文件夹,并且将该文件夹作为依赖仓库:

    repositories{
        flatDir{
            dirs 'aars'
        }
    }

通过如下方法(告知 Gradle 查找具有特定名称且扩展名为 .aar 的依赖库),我们可以添加任何文件到该目录下,并将其作为依赖:

dependencies{
    implementation name:'文件夹名', ext:'aar'
}

三、依赖概念

1. 配置

有时可能你不得不和一个只在特定设备上工作的 SDK 打交道,比如特定厂商的蓝牙 SDK。为了能够编译该代码,你需要将 SDK 添加至编译类路径。你并不需要添加 SDK 到你的 APK 中,因为其早已存在于设备中,这就是所谓的依赖配置。
Gradle 将多个依赖添加至配置,并将其命名为 集文件。(是被命名为xx,所以没什么其他的含义)。
下面是 Gradle 2.x.x版本 Android 应用或依赖库的标准配置:

  • compile
    • 默认的配置,在编译主应用时包含所有的依赖
    • 该配置不仅会将依赖添加至类路径,还会生成对应的 APK
  • apk
    • 只会将该依赖打包到 APK,而不会添加到编译类路径
    • 只适用于 JAR 依赖
  • provided
    • 不会将该依赖打包到 APK,会添加到编译类路径
    • 只适用于 JAR 依赖
  • testCompile
    • 添加用于测试的额外依赖库,不会添加到 release 版本中
  • androidTestCompile
    • 添加用于测试的额外依赖库,不会添加到 release 版本中

下面是 Gradle 3.x.x版本 Android 应用或依赖库的标准配置:

  • implementation
    • 只对当前的 Module 提供提供接口。
    • 依赖A通过 implementation 引用了依赖B,我们的项目引用了依赖A,那么我们的项目是无法访问依赖B的接口的
  • api
    • 2.x.x 版本中的 compile
  • compileOnly
    • 2.x.x 版本中的 provided
  • runtimeOnly
    • 2.x.x 版本中的 apk
  • unitTestImplementation
  • testImplementation
  • debugImplementation
  • releaseImplementation

2. 语义化版本

版本化是依赖管理的重要部分。将依赖添加到 JCenter 等依赖仓库时,约定遵循 了一套版本化规则,我们称之为 语义化版本
版本数字的格式一般为:major.minor.patch 数字按照下列规则依次增加:

  • 当做不兼容 API 变化时,major 版本增加
  • 当以向后兼容的方式添加功能时,minor 版本增加
  • 当修复一些 bug 时,patch 版本增加

3. 动态化版本

在某些情况下,你可能希望在每次构建你的应用或依赖时,都能够获取到最后的依赖,要想做到这一点,最好的实现方式是使用动态化版本。动态化版本的使用方式有很多种:

    dependencies{
        //获取最新的版本
        implementation 'com.android.support:support-v4:22.2.+'
        //获取最新的 minor 版本,并且 minor 版本至少是 2
        implementation 'com.android.support:appcompat-v7:22.2+'
        //获取依赖库的最新版本
        implementation 'com.android.support:recyclerview-v7:+'
    }

注: 动态化版本可能会因为 Gradle 自动获取的依赖版本不稳定而导致构建失败

四、总结

添加依赖到 Android 项目的多种方式,各种各样的依赖仓库,未使用依赖仓库时如何添加文件。
配置名称,语义化版本,动态化版本都是什么。
下一章:variants

你可能感兴趣的:(第三章 依赖管理)