Android Gradle 开发与应用 (七) : 实现打包自动复制文件插件

发布于:2024-04-19 ⋅ 阅读:(27) ⋅ 点赞:(0)

1. 前言

项目中遇到了一个问题 :

其中一个模块MyLibraryassets文件夹中,需要存放很多文件(每个文件对应一个功能)。

这样导致的问题是MyLibrary打出的这个aar包体积特别大。

如果把MyLibrary严谨地拆解成若干个Module又比较费时,对于现在业务现状来说也显得没那么必要。

那么能不能在上传MyLibrary这个aar的时候,自动复制相应的文件assets目录下,打出不同功能的aar呢 ?

这就需要自己开发一个Gradle插件来完成这个功能了。

本文环境

  • Android Studio 版本 : Android Studio Hedgehog | 2023.1.1
  • Gradle版本 : gradle-8.2
  • AGP版本 : 8.2.0
  • 项目结构 : 项目有app模块和MyLibrary模块,使用build.gradle (Groovy语言),appassets目录下,有test1.sotest2.sotest3.so这三个文件

2. 配置上传Maven仓库

首先我们把MyLibrary配置上传Maven的插件,也就是maven-publish

对于这部分功能不了解的同学可以先看我的这篇博客 : Android Module上传到Maven仓库 及 实现同时上传到多个Maven仓库

下面我们简单讲述一下

复制maven_upload.gradle到项目根目录下

apply plugin: 'maven-publish'

//TODO 这里填你Maven仓库的地址
def RELEASE_REPOSITORY_URL = "https://devops-maven.xxxxx.com/repository/yyyyy/"
//TODO 这里填你Maven仓库的账号
def NEXUS_USERNAME = "*********"
//TODO 这里填你Maven仓库的密码
def NEXUS_PASSWORD = "*********"

afterEvaluate {
   
    publishing {
   
        repositories {
   
            maven {
   
                name("ReleaseMaven")
                url = RELEASE_REPOSITORY_URL
                credentials {
   
                    username = NEXUS_USERNAME
                    password = NEXUS_PASSWORD
                }
            }
        }
        publications {
   
            Production(MavenPublication) {
   
                from components.release
                groupId = rootProject.ext.GROUP
                artifactId = rootProject.ext.POM_ARTIFACT_ID
                version = rootProject.ext.VERSION_NAME
            }
        }
    }
}

MyLibrary中依赖

rootProject.ext.GROUP = "com.heiko.mytest"
rootProject.ext.POM_ARTIFACT_ID = "mylibrary"
rootProject.ext.VERSION_NAME = "1.0.0"
apply from: "${
     project.rootDir}/maven_upload.gradle"

Sync一下,可以看到gradle中多了publishing这个文件夹,里面的publishProductionPublicationToReleaseMavenRepository就是用来将MyLibrary打包并上传到Maven仓库的Gradle命令了。

在这里插入图片描述

3. Gradle相关操作

3.1 复制文件

from是原目录,into是目标目录,include可以指定需要复制的文件,onlyIf可以用来判断是否执行复制任务。

task copyFiles(type: Copy) {
   
    from 'src/main/assets'
    into 'build/outputs/assets'
    //include 'test1.txt','test2.txt' //指定文件名
    include '**/*.txt' //根据*匹配符合要求的文件
    onlyIf {
   
         true
    }
}

3.2 删除文件

task myDeleteFilesInDir(type: Delete) {
   
	//delete 'src/main/assets/test1.txt'  //删除test1.txt
	//delete 'src/main/assets/test1.txt' //删除文件夹下所有的文件,assets文件也会被删除
    delete fileTree('src/main/assets') //删除文件夹下所有的文件,assets文件不会被删除
}

3.3 dependsOn

dependsOn表示一个任务需要另一个任务先完成,可以理解为依赖于需要先做,这意味着在执行这个任务之前,它所依赖的任务必须首先执行。

例如,如果你有一个任务叫做compile,它需要在clean任务之后执行,就可以像这样声明依赖关系:

task clearTask {
   
    doLast {
   
        println("执行 clear.doLast")
    }
}

task compileTask {
   
    doLast {
   
        println("执行 compile.dolast")
    }
}

compileTask.dependsOn(clearTask)

这样,每当你运行compile任务时,Gradle会首先运行clean任务。

在这里插入图片描述
执行compile任务的日志如下

> Task :app:clearTask
执行 clear.doLast

> Task :app:compileTask
执行 compile.dolast

BUILD SUCCESSFUL in 510ms

更通俗的理解 :
dependsOn就像是做饭的顺序:你首先需要准备食材,然后才能开始烹饪。同样地,如果你有一个任务依赖于另一个任务,那么你需要在开始当前任务之前先完成那个依赖任务。如果没有这种依赖关系,那么任务可能会在错误的时机执行,导致结果不正确或者出现错误。

//准备食材任务
task prepareFood(){
   }

//做饭任务
task cooking(){
   }

//做饭任务 依赖于 准备食材任务
cooking.dependsOn(prepareFood)

在这里插入图片描述

3.4 finalizedBy

finalizedBy用于指定一个任务另一个任务完成之后执行,可以理解为在完成后执行

Gradle中,finalizedBy用于指定一个或多个任务,这些任务将在关联任务执行完毕后执行,无论关联任务是否成功。可以把这个理解为一种清理或收尾的工作。

举个例子,我们有一个任务A,它被finalizedBy任务B,那就意味着在任务A执行完之后,无论任务A是否成功,任务B都会被执行。

这就好比一个厨师在做完一道菜(任务A)之后,无论这道菜是否做