辅助Android开发者在多模块工程间跨模块获取接口(或抽象类)的实现类的开源库,可实现模块的顺序初始化、业务的动态组合等实现。基于AGP和ASM开发。
通过AGP
实现的在Android
工程多模块之间获取接口或抽象类的实现类的实例的辅助工具。
通过在接口或抽象类上添加@Discoverable
注解、并在实现类上添加@Implementation
注解,就可以在工程中的任意模块中通过Discoveries
类获取该接口或抽象类的实例,辅助开发者在模块之间访问数据。
相比ARouter
等路由框架,Discovery
主要功能在编译期间工作,有更好的性能;并且只提供服务发现功能,开发者可实现更丰富的功能。
相比ServiceLoader
,Discovery
支持抽象类,以及可以获取实现类的class
对象,可以适配更丰富的其它框架。
演示工程:https://github.com/xiazunyang/DiscoveryDemo.git
Discovery
会在编译时扫描每个类文件,并将所有标记的类的信息通过ASM
注册到Discoveries
类中。
在android
工程app
模块的build.gradle
的适当位置添加以下代码:
plugins {
...
id("cn.numeron.discovery") version "2.0.0"
}
在android
工程中基础模块的build.gradle
文件中添加以下代码:
dependencies {
...
api("cn.numeron:discovery.library:2.0.0")
}
获取其它模块的业务服务
@Discovrable
注解@Discoverable
interface ISignInService {
/** 判断当前是否已登录 */
suspend fun isSignIn(context: Context): Boolean
/** 通过用户名和密码进行登录 */
suspend fun signInByPassword(username: String, password: String)
}
Implementation
注解@Implementation
class SignInServiceImpl: ISignInService {
override suspend fun isSignIn(context: Context): Boolean {
TODO("判断是否已经登录")
}
override suspend fun signInByPassword(username: String, password: String) {
TODO("根据提供的账号密码进行登录")
}
}
Discoveries
获取接口实例lifecycleScope.launch {
val signInService = Discoveries.getInstance<ISignInService>()
if (!signInService.isSignIn(requireContext())) {
//未登录, do something...
}
}
获取所有模块中的所有实例
@Discoverable
interface IInitializer {
fun init(application: Application)
}
//需要初始化的A模块
@Implementation(order = 0)
class AModuleInitializer: IInitializer {
override fun init(application: Application) {
//init a module
}
}
//需要初始化的B模块
@Implementation(order = 10)
class BModuleInitializer: IInitializer {
override fun init(application: Application) {
//init b module
}
}
Application
中获取所有实例并初始化class MyApplication: Application() {
override fun onCreate() {
//获取所有IInitiator的实现,并执行init方法
val initializerList = Discoveries.getAllInstances<IInitializer>()
initializerList.forEach {
//order数值小的实现类优先调用
it.init(this)
}
}
}
2.0.0
1.4.2
1.4.1
Implementation
注解中添加order
属性,用于给实现类排序。1.4.0
Discovery
不再参与创建这一类实现类的实例。Discoveries
中新增两个方法用于获取实现类的Class
,方便用户自己创建它们的实例。1.3.3
getAllInstances
没有获取到任何实例的时候,不再抛出异常,改为返回一个空的列表。1.3.2
ASM
的Option
降级至ASM7
。1.3.1
ASM
织入了错误的代码的问题。1.3.0
1.3.1
版本
1.2.2
Implementation
标记的类,要求必需拥有无参构造方法。1.2.1
Implementation
注解标记的类实现了多个接口时,会忽略掉未被Discovrable
注解标记的接口。1.2.0
Discovery
的配置选项,可配置实现类的处理方式。Scan
模式,即全局扫描,可配置为Mark
模式,需要使用Implementation
注解标记实现类,可免去扫描过程,以节省编译时间。1.1.0
APT
的实现,兼容java
项目,与KSP
任选其一即可。1.0.0
KSP
和AGP
实现主要功能。