自定义Gradle二进制插件

我们出于自己的目的,要开发实际业务场景的插件来辅助项目构建。 自定义二进制插件,可以使用 java,kotlin,或者 groovy 来编码,因为他们都是基于JVM的编程语言,最终都会生成class交给JVM去执行。groovy提供了更多插件相关的api,有一些情况用groovy能直接达成效果,而不需要去引入其他类库。

步骤

以kotlin为例:

创建一个java library

每个androidStudio版本的操作界面可能各不相同,这是 Android Studio Electric Eel | 2022.1.1 Patch 2 版本的截图。

2023-07-06-10-25-29-image.png

引入 必要的 依赖

包括两部分,一个是gradleApi,必须引入。

另外就是其他的,我们编写编码需要用到的其他依赖库,比如 发送网络请求的 okhttp,生成二维码的zxing ,接入华为云的 obs等等。

plugins {

    id 'java-library'
    id 'org.jetbrains.kotlin.jvm'  // kotlin依赖
}




dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation gradleApi() // 必须的gradle依赖



    // 引入其他工具类库
    implementation 'com.squareup.okhttp3:okhttp:3.14.6' // 使用最新版okhttp居然无法引用,很诡异
    implementation 'com.huaweicloud:esdk-obs-java-bundle:3.21.8' // 引入 华为云
    implementation 'com.google.zxing:core:3.4.1' // 二维码生成器
    implementation 'org.springframework:spring-core:2.5.6'
    implementation 'net.dongliu:apk-parser:2.5.3' // apk解析工具


}


新建一个Project实现类

import com.android.build.gradle.AppExtension
import com.tw.lib.bean.AutoUploadBean
import org.gradle.api.Plugin
import org.gradle.api.Project




class AutoUploadPlugin : Plugin<Project> {


    override fun apply(project: Project) {



        println("======== 自动上传插件初始化 =========")
        // 配置外来参数, 表示插件的使用者可以在gradle文件中写 相关的参数
        val autoUploadBean = project.extensions.create("autoUpload", AutoUploadBean::class.java)

        project.afterEvaluate {
            val appExtension = it.extensions.getByType(AppExtension::class.java)
            appExtension.applicationVariants.all { v ->
                v.outputs.all { out ->
                    val file = out.outputFile // 输出的apk文件
                    val name = out.name

                    project.tasks.create(
                        "auto_upload_$name",
                        AutoUploadTask::class.java,
                        file,
                        autoUploadBean
                    )
                }
            }

        }


    }
}

比如上面我要做一个实现自动上传的插件 AutoUploadPlugin ,它必须实现

Plugin<Project>接口,并实现其中的apply方法。方法内部写上你要做的操作。

一个project是由多个Task组合而成,下面的代码中,我我在apply方法中创建了一个名叫 autoUpload的 额外参数,并创建了一个名为 AutoUploadTask的 任务。

创建 AutoUploadTask 任务

public class AutoUploadTask extends DefaultTask {


    private File file;
    private final AutoUploadBean autoUploadBean;




    @Inject
    public AutoUploadTask(File file, AutoUploadBean autoUploadBean) {
        setGroup("autoUpload");
        this.file = file;
        this.autoUploadBean = autoUploadBean;
    }


    @TaskAction
    public void action() throws IOException {
        System.out.println("做你想做的事情");
    }
}


这里有一些要素必须提到,

首先,setGroup是自定任务的分组,这个分组最终会呈现在androidStudio右侧的gradle面板中。

其次,步骤3中执行了这么一段代码:

                    project.tasks.create(
                        "auto_upload_$name",
                        AutoUploadTask::class.java,
                        file,
                        autoUploadBean
                    )

这其实是在反射创建 AutoUploadTask对象,后面的file和autoUploadBean其实就是入参,所以我们必须提供一个带这两个参数的构造函数。

最后,在接收到 file和 autoUploadBean 外来参数之后,我们可以在 重写的action方法中使用它们来完成我们自己想要的的操作。

AutoUploadBean类的内容为:

open class AutoUploadBean {


    // 华为OBS账号
    var userName: String? = null
    // 华为OBS密码
    var pwd: String? = null
    // 华为OBS桶
    var domain: String? = null



    // 是否使用分段上传
    var usePartUpload: Boolean = false


    // 下载二维码的输出目录
    var buildRootDir: String? = null



}


到这里,插件基本上就编写完成了。

插件注册

每一个插件都有全局唯一一个 id ,这个id注册在 /src/main/resources/META-INF/gradle-plugins中,我们在 这个目录下,创建一个 自定义名称的com.tw.autoUpload.properties文件,自定义的名称就是我们插件的唯一ID,文件内容为:implementation-class=com.tw.lib.AutoUploadPlugin ,也就是我们自定义Plugin的全类名。

使用插件

在 要使用插件模块的build.gradle中

apply plugin:'com.tw.autoUpload'

或者

plugins {

    id 'com.android.application'
    id 'org.jetbrains.kotlin.android' 

    id 'com.tw.autoUpload'  // 使用插件
}

并且指定插件的额外参数:

autoUpload {
    userName 'c00293388'
    pwd 'Wd2A@zFJ1234'
    domain 'hwstaff_DigitalPayment'




    usePartUpload false


    buildRootDir 'C:\Users\zwx1245985\Desktop\saved'
}

执行插件任务

至此完成,经过编译之后,我们就能在 任务分组 autoupload之下,使用 auto_upload任务去执行上传操作了。

2023-07-06-10-40-27-image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYmTM5S6' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片