适用于想要模块化自己的应用,在开发一个完整应用的同时还可以将其中的部分提供成SDK供别的应用使用
模块间最大可能的解耦,依赖动态配置,application依赖模块的实现后模块自动添加,解除依赖也不影响应用正常运行,除了模块正常的对外接口,还具备提供mock修改的方式
账号模块,提供账号体系,含有一个登录界面
IM模块,提供im功能,含有一个IM的Fragment
主框架部分,提供MainActivity,作为其他模块的容器和入口
设置模块,其它模块可以向其注册需要设置的部分,其本身拥有一个Fragment需要显示在main模块
虽然需要最大程度的解耦,但是模块间的依赖是不可避免的,有的甚至是必须的,则每个模块分离出一个xx-common
模块,将其需要对外界暴露的部分以接口的形式定义在这个模块里,其它模块可以依赖这个xx-common
模块,但是不可以直接依赖xx
(即实现部分)
由于模块之间的解耦,模块的生命周期开始不可能通过被调用的方式开始,所以设计为广播的形式,各个模块继承ModuleInitReceiver,并按其注释在AndroidManifest.xml
中注册,包含先后两次广播,第一次是让各模块初始化自己,第二次则可以调用其它模块
模块的通信方式主要定义在modulecommounication包下。
模块发生的事件,在特定情境发出,用于通知或获取未知提供者的数据
通知事件,纯粹的事件,用于模块间的消息传递
获取数据的事件,被设计为需要其它模块提供数据时,而数据的提供方又不确定,发出此事件,由其它模块调用此事件的接口添加数据,事件发送方则可以在事件完成后获取此事件的数据
继承自GetDatasEvent
,在添加数据时为数据排序,保证数据的顺序
事件的插件,也可以理解为事件的拦截器,注册之后在事件发出前和事件结束后会回调插件,插件也可以在事件发出前拦截此事件,默认有一个EventLogPlug
的实现,用于为事件打印日志
模块向外提供的确定性的接口,例如account
模块为外提供的账号,实现方应在xx
部分实现ModuleFacade
接口,在xx-common
继承ModuleFacadeRepository
接口,并在初始化自己模块(参加模块生命周期部分)的时候调用
ModuleFacadeRepository#setFacade(ModuleFacade)
具体可参加代码示例
每个实现模块(xx
)应定义自己的xxConfig
类,用于自身模块的配置,且让application
方便的修改配置
配置的帮助部分在BaseConfig
中以静态方法定义,主要实现为以优先级的形式从数组中获取非空值
实现ConfigValue
接口的对象在数组中被解析时为其getValue()
方法返回的值,默认的实现PropertyValue
用于读取config.properties
的值,ResourceValue
用于读取资源文件的id
参见IMConfig的配置
注意:使用此用法时,在配置类初始化时由于常量的机制会导致所有属性初始化,涉及到性能问题时可以进行这里的测试
Activity跳转的插件,用于mock activity的跳转,任意的修改参数和回复