Gradle Builds Everything —— 产物输出

Gradle 打包的时候,还有个最终要的东西 —— 产物,这里的产物包括提供给别的项目的产物,今天咱们来说一讲,产物这个东西。
首先,看下咱们前面介绍了的 Configuration 对象,咱们看下这个接口声明知道这个对象有incomingoutgoing两种模式,incoming 咱们会用的多一点,就是从这个 Configuration 中获取产物,好比:html

dependency {
    implementation `aa:bb:1.0.0`
    implementation `cc:dd:1.0.0`
}

那么咱们可使用 project.getConfigurations().maybeCreate("implementation") 获取到 implementation 相关的信息,同时使用getIncoming()拿到 ResolvableDependencies 对象,而后能够调用getFiles()等直接拿到下载的文件。可是咱们前面知道,依赖下载来以后会根据一些规则作一些转换,好比咱们使用的 aar 是不能直接参与编译的,须要解压,解出资源,class 文件,R.txt 等参与编译,因此若是咱们想得到特定的类型,须要使用 artifactView 获取一个视图。java

Outgoing 和 Configuration 的关系

以上是 incoming 的用途,也就是 ResolvableDependencies,咱们如今要关注下 outgoing,就是 ConfigurationPublications,这个类用来注册产物信息。api

在注册产物前,咱们须要先定义一个 Configuration,由于 Configuration 里面配置了 Attributes —— 这个类用来标注产物的一些属性,只有过滤器对应上这个属性以后,咱们才能获取到相关的依赖。那么咱们首先想一想两个项目编译
项目结构app

这样的关系,咱们关注到 mylibrary 产出产物,成为 Producer(P),app 消化 mylibrary 的产物,称为 Consumer(C)。gradle

Attribute 的定义

那么这里,咱们定义,P 和 C 都有一些属性(Attribute),就像一对男女友同样,只有对上眼了才有可能互相选择在一块儿,他们互相挑选的方式就是使用 Attribute,在默认状况下,只有 Attribute 「相符」的状况下才能够被 C 消费,那么怎么定义相符呢?首先默认的规则是这样的:ui

  1. 若是 P 和 C 都拥有一个 attr name 相同的 attr,一旦 attr 的值不一致,则判断为不匹配。
  2. 若是 P 和 C 拥有对方没有的 attr,那么认为他们依然匹配。

P 和 C 的 attr 能够设置一些规则(Rule)来解决冲突和兼容问题,主要是 AttributeCompatibilityRule 和 AttributeDisambiguationRule 这两个类。spa

C 去找 P 的过程就是仅仅是经过 Attribute 过滤找,没有别的要素,那么知道这个以后,咱们想让 C 拿到咱们的结果的时候,只要让 P 的 attribute 匹配上就行了。debug

综上,咱们为了避免污染 mylibrary 这个项目中其余的 Conguration 的配置(每一个 Configuration 事实上就是一系列 配置的集合),咱们须要新建一个 Configuration。 Android Gradle Plugin 比较喜欢用 "apiElements" 和 "runtimeElements" 表明编译时和运行时的依赖。code

debugApiElements

咱们把 Attribute 放大看全一点:orm

3.png

记住咱们刚刚的原则:

默认状况下,若是有相关的属性,值必定是同样的。

我这里截图的是一个 application 工程,因此 AndroidTypeAttr 是 APK,若是是 AAR 的话,值就是 AAR。

咱们在 Consumer 里面的 ArtifactView,先获取到引入 mylibrary 的 Configuration 名称,并设置以上的几个 Attr,就能获取到这个产物了。

Outgoing 产物设置

上面咱们简单讲了下 Attribute 和 Configuration 之间的关系,后续我会专门开篇讲这个,所以咱们先点到为止。
下面咱们讲讲 Outgoing 的用法:

runtimeConfig.getOutgoing()
    .variants(variants -> variants.create("xxxx-artifact", configurationVariant -> {
        configurationVariant.artifact(artifactFile, configurablePublishArtifact -> {
            configurablePublishArtifact.setType("jar"); 
            configurablePublishArtifact.builtBy(bundleArtifact);
        });
    }));

其中, configurationPublishAritfact 是 ConfigurablePublishArtifact 这个类,为 artifactFile 这个文件定义了一些,具体能够看下这个类的定义:https://docs.gradle.org/curre...

其中 setType 是设置这个文件的 artifactType,默认是文件的后缀名,若是咱们改为其余 Consumer 的 ArtfactTransfomer 产物类型的话,Consumer 就能省去 Transform 这一步,直接使用咱们导出的产物。

因此,从这里咱们能够知道,虽然 mylibrary 的最终产物是 aar,可是 app 依赖 mylibrary 的时候,是并不须要 aar 这个产物的,由于在 aar 打包以前,这些产物都已经存在,彻底没有必要再解压提取一次。

builtBy 这个是定义了产物的依赖,若是 app 在 task 执行阶段须要提取这个产物的时候,就先要执行 builtBy 的这个 Task。

从这里咱们终于知道了 app 的 task 和 mylibrary 的 task 是经过产物这条链连在一块儿的。

结语

咱们经过本文知道了 Configuration Outing 的用途,后续会跟你们进行实战项目解说,咱们来自定义一个 Configuration 和产物类型,敬请期待。

相关文章
相关标签/搜索