阅读 1384

Android-Gradle-插件、依赖

前言

通过前两篇文章我们了解了Groovt语言Gradle基本命令、生命周期、Task,接下来主要了解关于插件以及依赖配置。

一、Project

build.gradle在配置阶段会生成project实例,在build.gradle中直接调用方法或属性,实则是调用当前工程project对象的方法或属性。

1.project的相关api

  • project(':app'){ } 指定project(app)的配置,源代码如下:
/**
     * <p>Locates a project by path and configures it using the given closure. If the path is relative, it is
     * interpreted relative to this project. The target project is passed to the closure as the closure's delegate.</p>
     *
     * @param path The path.
     * @param configureClosure The closure to use to configure the project.
     * @return The project with the given path. Never returns null.
     * @throws UnknownProjectException If no project with the given path exists.
     */
    Project project(String path, Closure configureClosure);
复制代码
  1. allprojects{ } 表示配置所有的project及其子project
allprojects {//fro project include repositories
    repositories {
        google()
        mavenCentral()
    }
}
复制代码
  1. subprojects{ } 表示配置所有的子project
//根目录下的build.gradle
subprojects {
    println("subprojects->$it")
}
输出:
> Configure project :
subprojects->project ':app'
复制代码
  1. buildscript{ } 表示项目配置构建脚本类路径
buildscript {//for ☆gradle include dependencies and repositories
    repositories {
        google()
        mavenCentral()
    }
    dependencies {//构建工具的依赖
        classpath(group: 'com.android.tools.build', name: 'gradle', version: '4.2.1')
    }
}
复制代码

2.ext扩展

使用ext可以对任意对象属性进行扩展。

  1. 在根项目中配置对其它project均可见
  2. 一般在root project中进行ext属性扩展,为子工程提供复用属性,通过rootProject直接访问。
  3. 任意对象都可以使用ext来添加属性:使用闭包,在闭包中定义扩展属性。直接使用=赋值,添加扩展属性。
//根build.gradle
this.ext.pop = "pop"
//ext{
//    pop = '1111'
//}
复制代码

4.使用gradle.properties以键值对形式定义属性,所有project可直接使用。

例如:我们在管理全局依赖配置文件一般会有config.gradle文件,一般写法如下:

ext {

    android = [
            compileSdkVersion: 29,
            minSdkVersion    : 21,
            targetSdkVersion : 29,
    ]

    androidxVersion = "1.0.0"

    supportDependencies = [
            supportV4: "androidx.legacy:legacy-support-v4:${androidxVersion}",
    ]
}
复制代码

然后在module中的build.gradle引入此文件使用其属性达到依赖版本统一。

二、插件

插件就是把独立或可公用的代码进行打包,已达到其它模块的复用。插件的应用都是通过Project.apply()方法完成的,并且插件分为两种,一种是脚本插件,另一种是二进制插件。

1.脚本插件

脚本插件就是直接编辑在gradle脚本文件中,然后通过apply plugin: PluginName 引用对应的插件,只能在此脚本中使用。

class MyPlugin implements Plugin<Project> {
    @Override
    void apply(Project target) {
    //此project对象就是 apply插件的Project对象
        println "MyPlugin apply"
    }
}

apply plugin: MyPlugin
复制代码

2.二进制插件

二进制插件就是实现了Plugin接口的插件,他们有plugin id,通过apply id引用。一般可以在单独的项目中实现,也可以在buildSrc目录下编写,由于buildSrc可应用于其他项目,那么在它项目初始化前就需要构建好buildSrc,所以他的构建时间会早于settings.gradle,接下来我们以buildSrc方式来实现, buildSrc目录下的插件,在运行时,会自动打包成jar并进行依赖,实现方式:

  • 创建moudle,并且命名为buildSrc。
  • 删除目录仅留下main文件夹,然后创建java文件夹(groovy也可以,只是实现的语言不同),和resources文件夹。
  • 新建resources->META-INF.gradle-plugins->com.empty.test.properties文件,并且写入
implementation-class=com.empty.test.MyTestPlugin
复制代码
  • 在buildSrc中配置 groovy依赖:apply plugin:'groovy'
  • 在app中apply plugin: MyTestPlugin 即可使用

结构

三、Transform

transform允许我们在class文件转为dex文件前操作编译好的class文件,每个Transform都是一个gradle task。具体实现如下:

class MyTestTransform extends Transform {

    @Override
    String getName() {
        return MyTestTransform
    }

    @Override
    Set<QualifiedContent.ContentType> getInputTypes() {
        return TransformManager.CONTENT_CLASS
    }

    @Override
    Set<? super QualifiedContent.Scope> getScopes() {
        return TransformManager.SCOPE_FULL_PROJECT
    }

    @Override
    boolean isIncremental() {
        return true
    }

    @Override
    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
        super.transform(transformInvocation)
        
        transformInvocation.inputs.each { TransformInput input ->
            input.jarInputs.each { JarInput jarInput ->
                //处理Jar
            }

            input.directoryInputs.each { DirectoryInput directoryInput ->
                //处理源码文件
            }
        }
    }
复制代码
  • getName():对应的Task名称
  • getInputTypes():确定对那些类型的结果进行转换,常用的是CONTENT_CLASS表示要处理java的class文件。
  • getScopes():指定插件的适用范围,常用的是TransformManager.SCOPE_FULL_PROJECT表示处理全部的class字节码。
  • isIncremental():是否支持增量更新
  • transform():具体的转换过程

之后在Plugin中注册这个Transform即可。

def appExtension = project.getExtensions().getByType(AppExtension.class)
appExtension.registerTransform(new MyTestTransform())
复制代码

四、依赖管理

关于依赖项的配置,我们常用的有implementation、api、compileOnly等,具体的解释官网中有, 链接在此

需要注意的是:

  • A implemetation B,B implemetation C,则A不能使用C。
  • A implemetation B,B api C,则A可以使用C。
  • A implemetation B,B implemetation C,C api D,则B可以使用D,但A不能使用D。
  • A implemetation B,B api C,C api D,这样A可以使用D

不管ABCD在何处被添加到类路径都一样,在运行时这些模块中的class都是要被加载的。

1.查看项目依赖

要查看项目依赖项 可使用命令: gradlew :app:dependencies 或者 gradlew :app:dependencies --configuration compile 也可以使用 gradlew build --scan 在网址上看。

同时Gradle也会有一部分优化,例如: 如果项目存在同一个依赖库的多个版本,默认选择最高版本、Gradle会自动排除重复的依赖、Gradle默认支持依赖传递等等。

命令输出

buildScan 其中

  • x.x.x (*) 该依赖已经有了,将不再重复依赖。
  • x.x.x -> x.x.x 该依赖的版本被箭头所指的版本代替。
  • x.x.x -> x.x.x(*) 该依赖的版本被箭头所指的版本代替,并且该依赖已经有了,不再重复依赖。

2.排除依赖

随着应用的范围不断扩大,它可能会包含许多依赖项,包括直接依赖项和传递依赖项(应用中导入的库所依赖的库)。如需排除不再需要的传递依赖项,可以使 exclude关键字:

dependencies {
    implementation('androidx.appcompat:appcompat:1.2.0') {
        exclude(group: 'androidx.core')
        exclude(group: 'androidx.arch.core', module: 'core-common')
    }
}
复制代码

使用全部排除:

// 在configurations{ } 中添加下面节点
configuration {
    all*.exclude module: 'name'
}
复制代码

3.指定依赖库版本

使用force来强行指定某个三方库的版本。

configurations.all {
   resolutionStrategy {
       force 'group:module:version'
   }
}
复制代码

五、发布插件到本地

先引入 maven 插件,再在 uploadArchives 加入上传的仓库地址与相关配置,配置中:groupId为组织或公司名称,artifactId为模块名称,version为当前版本号,这样 Gradle 在执行 uploadArchives 时将生成和上传 pom.xml 文件。

apply plugin: 'maven'

uploadArchives {
    repositories.mavenDeployer {
        repository(url: uri('../repostory'))
        pom.groupId = "com.empty.test"
        pom.artifactId = "mylibrary"
        pom.version = "1.0.0"
    }
}

implementation(group: 'com.empty.test', name: 'mylibrary', version: '1.0.0')
复制代码

发布远程一般为MavenCentral或者Jitpack,具体实现可自查。

六、总结

到这里,我们了解到什么是project、自定义插件、Transform、发布插件及依赖配置

文章分类
Android
文章标签