Android Studio自定义gradle插件

这是我...第一次写blog...

总感觉做开发的还是要写点这种分享,之前一直没有付出行动,嗯,因为懒,都是自己偷偷摸摸记点小笔记。年底刚换了个新环境,也不能总是搞业务吧,还是要有点规划和方向的。于是在主管的开导下,开始接触自定义gradle插件开发。因为今天是春节放假前最后一天呀,还是我生日.. 在这么个特殊的日子的,决定开始我的blog,先划一波水...


进入主题:

首先,插件可以以三种方式存在:

在我们构建的app项目下的build.gradle脚本中直接编写

在我们构建项目的rootProjectDir/buildSrc/src/main/groovy目录下

以单独的project存在

这里我采用第三种,单独创建Gradle Plugin 工程,这种方式的好处在于可以将插件打包发布,并很好的分享给使用者。


 创建Gradle Module

1.首先,file  ---> new module创建一个module, 这里用android library

图1


2.删除不必要的包/文件,只保留build.gradle文件和src/main目录。 图2 -> 图3的过程


图2
图3


3.由于gradle是基于groovy,因此,我们开发的gradle插件相当于一个groovy项目。所以需要在main目录下新建groovy目录,在groovy目录下新建包名,在该包下新建groovy文件,通过new->file->JbzPlugin.groovy来新建名为JbzPlugin的groovy文件。

图4

这里对我来说有个巨坑,Plugin类的创建一定要是通过new->file->JbzPlugin.groovy来新建名为JbzPlugin的groovy文件,注意:要直接在命名的时候就输入后缀.groovy!!!如果通过输入JbzPlugin再在选择文件类型的时候选groovy模版,这样不行,会一直报图5的error

图5

然后我在网上查了各种资料,什么删除项目的.gradle和本地的.gradle,各种clean,降低gradle版本(因为第一次创建出来的自定义gradle插件是可行的,但是后来可能看到了选择类型这种创建方式,忘记第一次怎么创建出来的,正好这两天发现自己gradle版本升到了4.1,以为是gradle版本升高了的关系,(关于gradle降版本要将gradle包下的整个wrapper都替换掉,不仅仅是修改gradle-wrapper.properties里面的版本号, gradle-wrapper.jar这个包也要替换掉)),结果都不行,郁闷了我好几天。。

奇怪的是通过new->file->JbzPlugin.groovy这种正确的创建方式创建出来的类底部会有报错的红线,提示class xxx(类名) already exites in xxx(包路径)  虽然不影响程序的运行。。。 最后解决之后我看了下本地的文件,打开文件所在地址,可以看到正确的创建方式文件名是JbzPlugin.groovy,而通过选择类型创建的文件名是JbzPlugin。 所以虽然在IDE中看不出两个类的区别,但是在本地还是有区别的。


4.新建JbzPlugin这个plugin类之后先不要在里面写class JbzPlugin implements Plugin等等代码,因为此时你还无法导入Plugin类,你要先去配置build.gradle文件,将默认的android的build.gradle替换成如下内容

图6

uploadArchives代码是将已经自定义好了插件打包到本地Maven库里面去了,你也可以选择打包到远程服务器中。其中,group和version是我们之后配置插件地址时要用到的。


5.好了,先将build.gradle配置好后我们回到JbzPlugin类中,这时候你已经引用apply plugin:'groovy'了(这个就是你自定义插件的开发语言,其中包含了各种功能类)。代码如下:

图7


6.现在,我们已经定义好了自己的gradle插件的plugin类,接下来就是告诉gradle,哪一个是我们自定义的plugin插件类,因此,需要在main目录下新建resources目录,然后在resources目录里面再新建META-INF目录,再在META-INF里面新建gradle-plugins目录。最后在gradle-plugins目录里面新建properties文件,注意这个文件的命名,你可以随意取名,但是后面使用这个插件的时候,会用到这个名字。比如,你取名为com.jbz.gradle.properties,在里面关联你的插件plugin类。代码如下:

                                    implementation-class=com.jbz.JbzPlugin

其中com.jbz是你的路径。

至此,你已经初步完成了你的自定义gradle插件。


7.点击AndroidStudio右侧的gradle工具,如下图所示:

图8

可以看到有uploadArchives这个Task,双击uploadArchives就会执行打包上传到你的本地仓库!执行完成后,你会发现root目录下多了一个repo文件,这就是你本地的Maven仓库,其中,com/jbz这几层目录是由我们的group指定,gradlelibrary是模块的名称,1.0.0是版本号(version指定)。

该图为所有的文件目录


8.使用自定义gradle插件

在app 的build.gradle 中添加apply plugin:'com.jbz.gradle', 这里的com.jbz.gradle就是resources包下的那个文件名前缀(这千万别写错了),然后再添加如下buildscript,你只需添加repo, repos是我自己测试时写的另一个maven仓库,依赖只需要写你自己的classpath,如:classpath'com.jbz.test:jbzlibrary:1.0.0'

这里先写buildscript,然后sync now,再添加apply plugin:'com.jbz.gradle',再sync now,否则会报错。此时你已经完成所以工作了,然后你会在app的other目录下找到一个名叫jbzTask的,这个就是你在plugin类中定义的jbzTask

双击jbzTask,你可以在控制台上看到输入的内容


好了,以上就是基本所有流程了。

写的时候自己都觉得乱。。感觉在搅一坨屎。。。知识点都在脑子里,个人表达能力实在有限。 还有就是重点。。。我要放假啦!!! 有缘再见~


其他1:如果因为修改了插件而导致app的build.gradle中报错,要先注释掉

其他1:记住,所有在插件上的更新操作,都要uploadArchives才能跑,如果你在插件中新写的代码有问题,而你已经uploadArchives导致app的build.gradle中报错,要先注释掉自定义的apply plugin: 'xxx',否则即使你修改正确,sync now还是无法成功。     例如一个gradle插件中已经有一个testTask, 当你在另一个gradle插件中再创建一个testTask时,第一次uploadArchives可以通过,但你再uploadArchives或者进行功能测试时会提示你testTask在xxxgradle中已经存在,此时如果你直接修改testtask命名再点sync now是无法通过的,因为第一次uploadArchives已经将代码编译进去了,你要先注释掉apply plugin: 'com.jbz.boom'(不编译这个gradle),再去修改task命名,然后uploadArchives更新编译,最后把注释消除,sync now。


其他2:

allprojects {

    afterEvaluate { project ->

        project.task('testTask') << {

            System.out.println("========================")

            println "Running tests for $project"

            System.out.println("========================")

        }

    }

}

这段代码写在rootproject的bulid.gradle中,当你执行testktask时就会打印出每个project的名称,右侧每个gradle的other下都会出现一个testTask表示当前的任务;写在某个subproject下时只代表当前gradle下的任务


还有其他一些高级点的比如Extension等东西,因为春节回家的心情已经快要按耐不住了,在此附加几个链接,我就不再重复了。。

https://www.jianshu.com/p/d53399cd507b

https://www.jianshu.com/p/af2b0a43133f

https://www.jianshu.com/p/bcaf9a269d96

推荐阅读更多精彩内容