Android Gradle生命周期与Gradle 自定义插件


插件是一种遵循一定规范的应用程序接口编写出来的程序。其只能运行在程序规定的系统平台下(可能同时支持多个平台),而不能脱离指定的平台单独运行。
Gradle就是一个Java程序,Gradle的插件可以在这个Java程序执行过程中执行额外的代码。

1.Gradle生命周期

  • 首先是初始化阶段(Initiliazation phase),对于multi-project build而言就是执行settings.gradle

  • Initiliazation phase的下一个阶段是Configration阶段。

    ​ Configration阶段的目标是解析每个project中的build.gradle。在这两个阶段之间,我们可以加一些定制化的Hook来处理一些逻辑。Gradle提供了API的支持了。

  • Configuration阶段完了后,整个build的project以及内部的Task关系就确定了。Configuration会建立一个有向图来描述Task之间的依赖关系。所以,我们可以添加一个HOOK,即当Task关系图建立好后,执行一些操作。自定义插件常会在afterEvaluate声明周期执行一定的代码逻辑。

  • 最后一个阶段就是执行任务了。任务执行完后,我们还可以加Hook。

2.生命周期监听方法

Project提供的声明周期方法

  • beforeEvaluate :解析各个工程build.gradle之前会执行。

  • afterEvaluate:这个方法回调在配置完成之后,也就是解析Build.gradle配置文件之后会执行,如果在配置文件,通过Extension的方式,配置了一些参数,如果想获取参数的值就需要在这个方法回调里边获取才行。

Gradle 提供的一些生命周期回调方法:

  • afterEvaluate(closure),

  • projectsEvaluated(closure),

  • buildFinished(closure),

   		StudyExtension studyExtension = project.getExtensions().create(PLUGIN_EXTENSION_NAME, StudyExtension.class);
		//
        System.out.println("lpf---------Extension");

        project.afterEvaluate(new Action<Project>() {
            @Override
            public void execute(Project project) {
                System.out.println("lpf---------afterEvaluate");
            }
        });

        Gradle gradle = project.getGradle();
        gradle.projectsEvaluated(new Action<Gradle>() {
            @Override
            public void execute(Gradle gradle) {
                System.out.println("lpf---------projectsEvaluated");
            }
        });


        gradle.buildFinished(new Action<BuildResult>() {
            @Override
            public void execute(BuildResult buildResult) {
                System.out.println("lpf---------buildFinished:"+buildResult.getAction());
            }
        });

//执行顺序     
> Configure project :app
lpf---------Extension
lpf---------afterEvaluate
lpf---------projectsEvaluated

最后会执行
lpf---------buildResult:Build

一般自定义插件 会在afterEvaluate这个回调里边创建task,并添加task执行依赖等

3.Gradle Project

Gradle为每个build.gradle都会创建一个相应的Project领域对象,在编写Gradle脚本时,我们实际上是在操作诸如Project这样的Gradle领域对象。所以可以通过project对象得到gradle,project记录着gradle文件的所有数据,通过生命周期回调方法可以在某个点执行自定义的代码逻辑。

4.Gradle Task

一个Project由一个或者多个Task组成,它是构建过程中的原子任务,

build.gradle的执行过程: Configuration阶段->任务执行前的操作->执行阶段->任务执行后的操作,了解了这个过程就可以根据需求自定义自己的插件,比如:可以使编译class、上传jar包等

task 创建task一般需要制定所属的group组,并指明依赖那个任务。

5.自定义gradle插件的流程

5.1.编写一个插件类,实现Plugin
class JiaGu360Plugin implements Plugin<Project> {
    
    

    @Override
    void apply(Project project) {
    
    
        //获取Extension
        Jiagu360Extension jiaGu360Extension = project.extensions.create("JiaGu360", Jiagu360Extension)
        //配置解析完gradle文件之后操作,在这个回调可以拿到配置信息
        project.afterEvaluate {
    
    
            //得到AppExtension 从上面得到applicationVariants变体 
            // 如果没有配置产品维度的话 变体只有两个:debug和release
            AppExtension android = project.extensions.android
            android.applicationVariants.all {
    
     ApplicationVariant variant ->
                    //得到配置的签名信息
                    SigningConfig signingConfig = variant.signingConfig
                    variant.outputs.all {
    
     BaseVariantOutput output->
                            //得到输出apk文件
                            File apk = output.outputFile
                            //创建Task 任务
                            JiaguTask360 jiaguTask = project.tasks.create("jiaGu360${
      
      variant.baseName.capitalize()}", JiaguTask360)
                            //传参数
                            jiaguTask.mJiaGu360 = jiaGu360Extension
                            jiaguTask.mSigningConfig = signingConfig
                            jiaguTask.mApk = apk
                            
                             //增加任务依赖 构建成功后会自动执行加固task
                             variant.getAssembleProvider().get().dependsOn(project.getTasks().findByName("clean"))
                             jiaguTask.dependsOn(variant.getAssembleProvider().get())

                    }
            }
        }
    }
}

  • project.extensions.create(“jiagu”, Jiagu) :通过project.extensions 得到一个ExtensionContainer,调用ExtensionContainer的create方法创建extensition,这个是在gradle配置参数使用的。
  • 得到AppExtension 从上面得到applicationVariants变体 ,如果没有配置产品维度的话 变体只有两个:debug和release
  • project.tasks.create():创建task任务,名称后边追加变体,这样容易区分
  • 给task添加依赖,可以自动触发,打好apk安装包自动触发360加固的task
5.2编写task任务
class JiaguTask360 extends DefaultTask {
    
    

    Jiagu360Extension mJiaGu360
    SigningConfig mSigningConfig
    File mApk

    JiaguTask360() {
    
    
        group = "jiagu360"
    }

    @TaskAction
    def doAction() {
    
    
        project.exec {
    
    
            // java -jar jiagu.jar -login user password
            it.commandLine("java", "-jar", mJiaGu360.jiaguTools, "-login", mJiaGu360.userName, mJiaGu360.password)
        }

        if (signingConfig) {
    
    
            project.exec {
    
    
                // java -jar jiagu.jar -importsign  xxxx
                it.commandLine("java", "-jar", mJiaGu360.jiaguTools, "-importsign", mSigningConfig.storeFile.absolutePath,
                        mSigningConfig.storePassword, mSigningConfig.keyAlias, mSigningConfig.keyPassword)
            }
        }
        project.exec {
    
    
            // java -jar jiagu.jar -jiagu  xxxx
            it.commandLine("java", "-jar", mJiaGu360.jiaguTools, "-jiagu", mApk.absolutePath,
                    mApk.parent, "-autosign")
        }


    }
}
  • 继承DefaultTask ,在构造方法里边定义一个group,这样task就会出现在一个自定义的group里边了,方便查找管理。
  • def doAction() :定义一个方法,记得一定添加 @TaskAction注解,这样当执行这个task的时候就可以执行这个方法了。
  • 通过命令的方式:登录360加固工具->上传签名配置->执行加固逻辑
5.3.配置properties文件

在main下面新建resources->META-INF->gradle-plugins 这三个文件夹,注意名称不能错了,否则找不到插件。

然后新建com.meishe.jiagu360.properties,其中:com.meishe.jiagu360这个就是插件的名称,使用依赖的时候就是用的这个。

implementation-class=com.meishe.plugin.JiaGu360Plugin
5.4配置插件的build.gradle
apply plugin: 'groovy'

dependencies {
    
    
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.tools.build:gradle:4.2.0'
    implementation gradleApi()
}

sourceCompatibility = "7"
targetCompatibility = "7"


//配置上传本地仓库
apply plugin:'maven-publish'

publishing{
    
    
    publications{
    
    
        Jiagu(MavenPublication){
    
    
            from components.java  //要把源码生成的jar包上传
            groupId 'com.meishe'
            artifactId "jiagu360"
            version "1.0"
        }
    }
}
5.5使用自定义的插件

首先需要先上传本地maven仓库才行,或者上传私服maven仓库,如果本地仓库可以在

/home/ms/.m2/repository/com/meishe/jiagu360/1.0 路径下看到上传到本地仓库的插件

image-20220522235132095

在app下面的build.gradle增加依赖:

apply plugin:'com.meishe.jiagu360'
JiaGu360{
    
    
    userName "加固帐号用户名"
    password "加固帐号密码"
    jiaguTools "加固工具路径"
}

在最外层gradle增加
calsspath "com.meishe:jiagu360:1.0"

在这里截图可以看到生成了jiagu360的group,并看到了两个task,双击执行就可以了。

在这里插入图片描述

6.0插件的debug调试配置

6.1通过Edit Configurations 点击左上角的+按钮,创建一个remote,随便取个名字

在这里插入图片描述

将这段复制出来:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

6.2找到我们创建的task,鼠标右击弹出菜单,点击:create Run Configurations 选项,将拷贝出来的内容粘贴到VM options

在这里插入图片描述

这样在Run Configurations看到配置的任务了

在这里插入图片描述

6.3在需要调试的位置打上断点,右击Jiagu360Debug任务 点击debug按钮,然后再右击点击jiagu360 任务的debug按钮,就可以调到调试的断点位置了

image-20220523002241207

到了断点的位置,并拿到了在build.gradle配置的参数的信息了,上面信息需要按照真实信息填写就可以了

猜你喜欢

转载自blog.csdn.net/u014078003/article/details/124919321
今日推荐