第三章 依赖管理

第三章 依赖管理

我们只需要在构建文件 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 币乎最近很火,身边只要接触过区块链的人都在谈论币乎,都嚷嚷着要到币乎上写文章赚钱,生怕去玩了钱就被别人赚走了。 让...
    文致斌阅读 271评论 0 0
  • 我们都是来自各方的一群孩子,离开了温暖的家庭,只身一人来到一个陌生的城市,开始我们的求学生涯。我们从陌生到相识相知...
    笑而丶不語阅读 274评论 0 0
  • 1,毛姆说:如果对别人撒谎有时确有必要的话,对自己撒谎则在任何时候都是卑劣的。 混球的反义词,是:善良的笨蛋。 善...
    laoqin阅读 445评论 0 0
  • 思念化成一堵墙 墙角埋下激情的种子 发芽?发芽? 还是寂灭。 承受不起的,没有回音的爱慕 墙外的人看不到墙里 是怎...
    大秦小肆阅读 188评论 0 1