AutoRegister
Introduction: android 中实现自动注册的 gradle 插件
Tags:
前言
此插件要解决的问题是:
- 工厂模式中工厂创建的产品需要注册到工厂类中,每新增一个产品要修改一次工厂类的代码
- 策略模式中所有策略需要注册到管理类中,每新增一种策略需要修改一次管理类的代码
- 接口及其管理类在基础库中定义,其实现类在不同的 module 中,需要在主工程中进行注册,每新增一个实现类注册需要手动添加
- 比如在做组件化开发时,组件注册到主 app 中需要在主 app 的代码中 import 组件类进行注册,代码侵入性强
使用此插件后,在编译期(代码混淆之前)扫描所有打到 apk 包中的类,将符合条件
的类收集起来,并生成注册代码到指定的类的 static 块中,自动完成注册
名词解释
- scanInterface : (必须)字符串,接口名(完整类名),所有直接实现此接口的类将会被收集
- codeInsertToClassName : (必须)字符串,类名(完整类名),通过编译时生成代码的方式将收集到的类注册到此类的 codeInsertToMethodName 方法中
- codeInsertToMethodName: 字符串,方法名,注册代码将插入到此方法中。若未指定,则默认为 static 块,(方法名为:
) - registerMethodName : (必须)字符串,方法名,静态方法,方法的参数为 scanInterface
- scanSuperClasses : 字符串或字符串数组,类名(完整类名),所有直接继承此类的子类将会被收集
- include : 数组,需要扫描的类(正则表达式,包分隔符用/代替,如: com/billy/android/.*),默认为所有的类
- exclude : 数组,不需要扫描的类(正则表达式,包分隔符用/代替,如: com/billy/android/.*),
功能简介
在 apk 打包过程中,对编译后的所有 class(包含 jar 包中的 class)进行扫描,将 scanInterface 的实现类 或 scanSuperClasses 的子类扫描出来,并在 codeInsertToClassName 类的 static 块 中生成注册代码,如 demo 中:
public class CategoryManager {
static
{
CategoryManager.register(new CategoryA()); //scanInterface 的实现类
CategoryManager.register(new CategoryB()); //scanSuperClasses 的子类
}
}
扫描的类包含:通过 maven 依赖的库、module 依赖的 library、aar 包、jar 包、AIDL 编译后的类及当前 module 中的 java 类
要点:
- 生成的代码为: registerClassName.registerMethodName(scanInterface)
- 扫描到的类不能为接口或抽象类,并且提供 public 的无参构造方法(abstract 类或 scanInterface 的子接口需要添加到 exclude 中)
- 如无特殊需求,codeInsertToClassName 尽量与 registerClassName 是同一个类(registerClassName 不配置则默认为 codeInsertToClassName)
使用方式
在工程根目录的 build.gradle 中添加依赖:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.0.0' classpath 'com.billy.android:autoregister:x.x.x' } }
- 在 application 的 build.gradle 中添加配置信息:
更新日志:apply plugin: 'auto-register' autoregister { registerInfo = [ [ 'scanInterface' : 'com.billy.app_lib_interface.ICategory' , 'scanSuperClasses' : ['com.billy.android.autoregister.demo.BaseCategory'] , 'codeInsertToClassName' : 'com.billy.app_lib_interface.CategoryManager' //未指定 codeInsertToMethodName,默认插入到 static 块中,故此处 register 必须为 static 方法 , 'registerMethodName' : 'register' // , 'exclude' : [ //排除的类,支持正则表达式(包分隔符需要用/表示,不能用.) 'com.billy.android.autoregister.demo.BaseCategory'.replaceAll('\\.', '/') //排除这个基类 ] ], [ 'scanInterface' : 'com.billy.app_lib.IOther' , 'codeInsertToClassName' : 'com.billy.app_lib.OtherManager' , 'codeInsertToMethodName' : 'init' //非 static 方法 , 'registerMethodName' : 'registerOther' //非 static 方法 ] ] }
- 在 application 的 build.gradle 中添加配置信息:
2018-08-18 V1.4.1
支持增量编译及其开关(默认开启,可通过配置cacheEnabled = false
来关闭增量编译,参考 demo)
2018-05-18 V1.3.0
修复 gradlew build 命令同时打 debug 和 release 包时,release 包中注册的代码重复的问题
2018-03-12 V1.2.0
解决同时编译多个 application module(点击 Build -> Rebuild/Build APKs)时出现错误注册的问题
2018-01-15 V1.1.3
解决 windows 的兼容性问题
2018-01-09 V1.1.0
兼容 java8
2017-12-17 V1.0.5
- 从本仓库中删除为ARouter定制的路由自动注册插件,已提供 ARouter 专用精简版路由自动注册插件并提交PR到 ARouter 仓库
- 解决使用继承后,scanSuperClasses 指定的类本身不会被自动注册的 bug,并升级为 V1.0.5
scanSuperClasses 参数指定的父类不需要自动添加到 exclude 中
抽象类不会被添加到自动注册列表。
2017-12-06
新增ARouter定制的路由自动注册插件:auto-register-for-arouter
classpath 'com.billy.android:auto-register-for-arouter:1.0.0'
apply plugin: 'auto-register-for-arouter'
2017-11-21 V1.0.4
生成的注册代码不再局限于 static 块中,可以在任意方法(codeInsertToMethodName)中
需要注意: codeInsertToMethodName 与 registerMethodName 必须同时为 static 或非 static