Android 自定义 gradle 插件

easy-gradle-plugin

  • github 项目地址 https://github.com/drumge/easy-gradle-plugin

  • 这是一款让你更容易使用 android gradle 自定义插件的插件。可以帮助开发者省去了解 gradle 脚本,groovy 学习成本,只关注需求的实现逻辑,完全可以使用 Java 语言来实现自己的 gradle 插件。

  • 使用 easy-gradle-plugin 可以很方便的自定义 transform 不用关心任何发布等相关繁琐的操作,直接继承 BaseEasyTransform 类并配置插件 transform = new ExampleTransform(project) 即可。

  • 当项目中有多个自定义的 gradle 插件时,每个插件自定义的 transform 操作 jar 库,可能存在每个 transform 都会解压 jar 包并压缩 jar 包等,这些操作是很耗时的,有多个插件时,编译速度变慢是硬伤。使用 easy-gradle-plugin 可以配置多个插件,每个插件可以对应一个 transform, 但是不需要多次解压、压缩的过程,只会有一次。

  • 对于不了解 gradle 的开发者来说开发自定义 gradle 插件还是需要了解一些相关的知识的,至少得对 gradle 脚本编译有初步的了解,并且了解 groovy 语言的使用,因为 gradle 脚本和自定义插件都是使用 groovy 来开发的。这个时候 easy-gradle-plugin 可以帮开发者更容易的实现自己的 gradle 插件。

  • 大部分情况下 android 应用开发者并不需要了解 gradle 的使用及原理,平时使用最多的可能就是 dependencies 添加一个依赖库了。如果需要对项目做 AOP 切面编程或者一些特殊的需求,可能就需要使用到 gradle 自定义插件了。例如比较受开发者深受喜欢的EventBus, Butterknife 都使用了自定义 gradle 插件来在编译期间生成一些辅助的类以及插入代码实现相关的功能,可以避免在运行期间使用反射。一般来说框架中使用了反射都可以考虑使用 AOP 思想来在编译期间生成代码来避免反射来实现相同的功能,并且使用更加便捷。

gradle 配置

  • 在 android 项目根目录的 build.gralde 中配置
 buildscript {

    repositories {
        maven{ url uri('https://oss.sonatype.org/content/groups/staging')}
    }
    dependencies {
        // 添加 easy-gradle-plugin 插件, 主要是为了 apply plugin: 'com.drumge.easy.plugin'
        classpath "com.github.drumge:easy-plugin:0.0.2"
    }
 }

 allprojects {
    repositories {
        maven{ url uri('https://oss.sonatype.org/content/groups/staging')}
    }
 }
  • 在 application 所在的 build.gradle 中配置
apply plugin: 'com.drumge.easy.plugin'
easy_plugin {
    enable = true

    plugins{
        // 包含多个插件,每个插件名字可以自定义,只是插件内部可能会关系名字,比如 example
    }
}

以上就是所有使用 easy-gradle-plugin 的全部配置。实现自己的插件之后,并配置以上的两个地方就可以愉快的使用自定义 gradle 插件了。

示例演示说明

  • 创建本地插件
  1. 在项目中创建一个 Java Library 类型 module,可参考 plugin-example 和 java-plugin-example。
  2. 在创建 module 下的 build.gradle dependencies 中加入依赖 implementation "com.github.drumge:easy-plugin-api:0.2.2"
  3. 在 build.gradle 最后加入 apply from: "${rootDir.absolutePath}/build_scrip/plugin_build.gradle" 使用 plugin_build.gradle 脚本中自定义的 task, 包含 buildPlugin 和 cleanPlugin,分别编译本地插件和清除插件。
  4. 根据需要创建类,可分别实现 easy-plugin-api 中的接口类,或者继承抽象类并实现需要的接口。
  5. 执行 buildPlugin 生成插件 jar 并默认拷贝到 rootDir/plugin_libs 目录,生成目录可在 plugin_build.gradle 脚本中手动修改。
  6. 在根目录 build.gradle 添加本地插件依赖的 classpath
   buildscript {
       dependencies {
           // 添加本地插件依赖, 其中 plugin_libs 目录可以在 plugin_build.gradle 中手动修改
           classpath fileTree(dir: 'plugin_libs', include: ['*.jar'])
       }
   }
  1. 在 application module 下的 build.gradle 中添加插件配置,以项目中的 example-plugin 和 java-example-plugin 为例
    apply plugin: 'com.drumge.easy.plugin'

    import com.drumge.plugin.example.ExampleExtend
    import com.drumge.plugin.example.ExamplePlugin
    import com.drumge.plugin.example.ExampleTransform
    import com.drumge.plugn.example.java.JavaPlugin
    import com.drumge.plugn.example.java.JavaExtend
    import com.drumge.plugn.example.java.JavaTransform

    easy_plugin {
        enable = true
        plugins{
            example { // 使用 groovy 语言实现的插件,详细请看 plugin-example module
                plugin = new ExamplePlugin(project)
                // 可自定义功能丰富的 extend
                extend = ExampleExtend.createExtend(project) { ExampleExtend extend ->
                    extend.enable = true
                    extend.infos {
                        info1 {
                            infoVersion = '0.0.1'
                        }
                        info2 {
                            infoVersion = '0.0.2'
                        }
                        info3 {
                            infoVersion = '0.0.3'
                        }
                    }
                }
                // 自定义 transform
                transform = new ExampleTransform(project)
            }

            java_example { // 使用 Java 语言实现的插件,详细请看 java-plugin-example module
                plugin = new JavaPlugin(project)
                // 可自定义功能丰富的 extend
                extend = JavaExtend.createExtend(project) { JavaExtend extend ->
                    extend.enable = true
                    extend.infos {
                        java_info1 {
                            infoVersion = '0.0.1'
                        }
                        java_info2 {
                            infoVersion = '0.0.2'
                        }
                        java_info3 {
                            infoVersion = '0.0.3'
                        }
                    }
                }
                transform = new JavaTransform(project)
            }
        }
    }
  • 创建远程插件
  1. 创建远程插件是指,本地生成插件之后上传到 maven 远程仓库,并通过 dependencies 依赖远程仓库的方式导入 classpath。
  2. 创建步骤跟本地插件是一样的,不同的地方在于,不是使用 buildPlugin 来生成插件,需要通过发布 maven 仓库相关的步骤。这里就不展开讲,需者可自行搜索,资料还是挺多的。
  3. 发布到 maven 仓库之后,需要在根目录下的 build.gradle buildscript { repositories { }} 中添加 maven 库的地址。接着像其他的插件一样添加 classpath 即可,如 classpath "com.github.drumge:kvo-plugin:0.2.2"
  4. application module 下的 build.gradle 配置同本地插件是一样的
   apply plugin: 'com.drumge.easy.plugin'

   import com.drumge.kvo.plugin.KvoPlugin
   import com.drumge.kvo.plugin.KvoTransform
   easy_plugin {
       enable = true
       plugins{
           kvo { // 使用了 easy-gradle-plugin 的实践项目,详情可跳转 https://github.com/drumge/kvo.git 了解
               plugin = new KvoPlugin(project)
               transform = new KvoTransform(project)
           }
       }
   }

接口说明

  • 接口的使用可以参考 example-plugin 和 java-example-plugin, 或者 kvo库

  • 下边简单举例说明一下

easy_plugin {
    plugins {
        exmple { // 名字可自定义
            // 以下的 plugin, extend, transform 名字不能改,并且分别对应着指定的类型, 这些参数的接口类定义在 easy-plugin-api 中。plugin -> IPlugin, extend -> IExtend, transform -> IEasyTransform
            // plugin, extend, ransform 三者并不是必须的,可以只实现其中的任何一个
            plugin = new ExamplePlugin(project) // class ExamplePlugin implements IPlugin
            extend = new ExampleExtend() // class ExampleExtend implements IExtend
            transform = new ExampleTransform(project) // class ExampleTransform extends BaseEasyTransform
        }
    }
}

实战项目

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容