美文网首页
AutoRegister 使用总结(模块化自动注册方案)

AutoRegister 使用总结(模块化自动注册方案)

作者: 太极1 | 来源:发表于2020-04-15 10:53 被阅读0次

    背景

    公司之前模块化开发中,使用了AutoRegister作为自动注册组件方案,且ARouter中也使用了AutoRegiser

    主要原理

    在编译时,扫描即将打包到apk中的所有类,将所有组件类收集起来,通过修改字节码的方式生成注册代码到组件管理类中,从而实现编译时自动注册的功能,不用再关心项目中有哪些组件类了。

    特点

    不需要注解,不会增加新的类;性能高,不需要反射,运行时直接调用组件的构造方法;能扫描到所有类,不会出现遗漏;支持分级按需加载功能的实现。

    使用

    名词介绍

    scanInterface : (必须)字符串,接口名(完整类名),所有直接实现此接口的类将会被收集
    codeInsertToClassName : (必须)字符串,类名(完整类名),通过编译时生成代码的方式将收集到的类注册到此类的codeInsertToMethodName方法中
    codeInsertToMethodName: 字符串,方法名,注册代码将插入到此方法中。若未指定,则默认为static块,(方法名为:)
    registerMethodName : (必须)字符串,方法名,静态方法,方法的参数为 scanInterface
    scanSuperClasses : 字符串或字符串数组,类名(完整类名),所有直接继承此类的子类将会被收集
    include : 数组,需要扫描的类(正则表达式,包分隔符用/代替,如: com/billy/android/.),默认为所有的类
    exclude : 数组,不需要扫描的类(正则表达式,包分隔符用/代替,如: com/billy/android/.
    ),

    在对应的module的gradle中
    都需要添加

    apply plugin: 'auto-register'
    

    在app module中添加

    project.ext.registerInfoList = [
        [
            'scanInterface'             : 'com.billy.app_lib_interface.ICategory'
            // scanSuperClasses 会自动被加入到exclude中,下面的exclude只作为演示,其实可以不用手动添加
            , '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方法
        ],
    

    第一个注册中插入到static必须提供static方法注册

    static void register(ICategory category) {
            if (category != null) {
                CATEGORIES.put(category.getName(), category);
            }
        }
    

    在第一个注册中实现中会自动插入以下代码

    public class CategoryManager {
      static
      {
        CategoryManager.register(new CategoryA()); //scanInterface的实现类
        CategoryManager.register(new CategoryB()); //scanSuperClasses的子类
      }
    }
    

    在第二个注册中,指定了codeInsertToMethodName,会在init()方法中调用registerOther方法,完成实现类注册

     public OtherManager() {
            init();
        }
    
        private void init () {
    
        }
    
        private void registerOther(IOther other) {
            if (other != null) {
                LIST.add(other);
            }
        }
    

    在module之间的调用中,可以通过moduleManger的list或者map获取到需要的已经注册的module实例,类似调用module的public方法即可

     CategoryB categoryB= (CategoryB) CategoryManager.getCategory("CategoryB");
            if (categoryB!=null){
                categoryB.doSth();
            }
    

    原理介绍

    github

    相关文章

      网友评论

          本文标题:AutoRegister 使用总结(模块化自动注册方案)

          本文链接:https://www.haomeiwen.com/subject/pkjqvhtx.html