Discovery
通过在下层模块中创建接口(或抽象类)并标记@Discoverable
注解,然后在其它上层模块中创建实现类并标记@Implementation
注解,就可以在工程中的任意模块中通过Discoveries
类获取该接口或抽象类的实例,辅助Android
开发者在模块之间访问数据。
原理及同类框架的差异
Discovery
会在编译时扫描每个类,并将所有标记的类的信息通过ASM
注册到Discoveries
类中。- 相比
ARouter
等路由框架的服务发现功能,Discovery
主要功能在编译期间工作,不会在运行时扫描dex
,有更好的性能。 - 相比
ServiceLoader
,Discovery
支持抽象类,以及可以获取实现类的class
对象,可以适配更丰富的其它框架。
开源地址
安装
-
在根模块的
build.gradle
的适当位置添加以下代码:buildscript { repositories { ... mavenCentral() } dependencies { ... //添加Discovery插件 classpath("cn.numeron:discovery.plugin:latest_version") } } 复制代码
-
在业务模块的
build.gradle
文件中添加以下代码:api("cn.numeron:discovery.library:latest_version") 复制代码
-
在主模块的
build.gradle
文件中添加以下代码:plugins { id("com.android.application") ... //应用Discovery插件 id("discovery") } 复制代码
多模块工程顺序初始化示例
- 在基础模块中创建一个接口,并标记
Discoverable
注解:
@Discoverable
interface Initializer {
fun init(application: Application)
}
复制代码
2.其它需要初始化的模块中创建Initializer
的实现类,并标记Implementation
注解,以及指定order
的值,order
的数值越小,优先级越高:
//需要初始化的A模块
@Implementation(order = 0)
class AModuleInitializer: Initializer {
override fun init(application: Application) {
//init a module
}
}
复制代码
//需要初始化的B模块
@Implementation(order = 10)
class BModuleInitializer: Initializer {
override fun init(application: Application) {
//init b module
}
}
复制代码
3.在Application
的onCreate
方法中获取所有Initializer
的实例,并遍历它们,调用init
方法:
class MyApplication: Application() {
override fun onCreate() {
//获取所有IInitiator的实现,并执行init方法
val initializerList = Discoveries.getAllInstances<IInitializer>()
initializerList.forEach {
//order数值小的实现类优先调用
it.init(this)
}
}
}
复制代码
功能扩展
可以看到,Discovery
只是帮助开发者处理了服务的注册与发现的问题,具体要怎么实现,全由开发者自行决定,比如搞个有向无环图
、顺序启动
之类的功能,都可以随意扩展。