一个全新的 Android 组件化通信工具
ComponentBus 这个项目已经内部使用了一段时间, 经过几次迭代.
他非常小巧, 且功能强大, 并且配有 IDEA 插件作为辅助.
ComponentBus 利用 ASM、KSP, 使组件间的通信变得简单且高效.
第一步组件间通信
新建一个 Module, 我们给他添加一个接口
@Component(componentName = "Test")
object ComponentTest {
@Action(actionName = "init")
fun init(debug: Boolean) {
...
}
@Action(actionName = "getId")
fun getId(): String {
return "id-001"
}
@Action(actionName = "openUserPage", interceptorName = ["LoginInterceptor"])
fun openUserPage() {
val newIntent = Intent(MyApplication.application, UserActivity::class.java)
newIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
MyApplication.application.startActivity(newIntent)
}
}
我们可以看到, 任何方法、参数、返回值都可作为通信 Action, 只要给他加上 Action 注解.
并且我们可以给他添加拦截器, 当条件不满足时进行拦截, 并做其他操作.
由于 module 间没有依赖, 返回值应该是所有 module 都可以引用到的类型.
组件间调用, 参数默认值目前不支持使用.
第二部调用其他组件API
新建一个 Module, 我们调用另一个 Module 的 API
ComponentBus.with("Test", "init")
.params("debug", true)
.callSync<Unit>()
val result = ComponentBus.with("Test", "getId")
.callSync<String>()
if (result.isSuccess) {
val id = result.data!!
}
就是这么简单, 不需要接口下沉.
这里有个问题, 那就是 componentName、actionName 都是字符串, 使用上不方便, 需要查看名称、复制.
为了解决这个问题, 我专门开发了一款 IDEA 插件, 辅助使用.
IDEA 插件
插件搜索 componentBus
拦截器
全局拦截器
/**
* 全局日志拦截器
*/
object LogGlobalInterceptor : GlobalInterceptor() {
override suspend fun <T> intercept(chain: Chain) = chain.proceed<T>().apply {
UtilsLog.log("Component: ${chain.request.componentName}${Utils.separatorLine}Action: ${chain.request.action}${Utils.separatorLine}Result: ($code) $msg $data", "Component")
}
override fun <T> interceptSync(chain: Chain) = chain.proceedSync<T>().apply {
UtilsLog.log("Component: ${chain.request.componentName}${Utils.separatorLine}Action: ${chain.request.action}${Utils.separatorLine}Result: ($code) $msg $data", "Component")
}
}
普通拦截器
/**
* 判断是否是登录的拦截器
* 未登录会进入登录页面
*/
object LoginInterceptor : IInterceptor {
override suspend fun <T> intercept(chain: Chain): Result<T> {
return if (UsercenterComponent.isLoginLiveData.value == true) {
chain.proceed()
} else {
showLogin()
Result.resultError(-3, "拦截, 进入登录页")
}
}
override fun <T> interceptSync(chain: Chain): Result<T> {
return if (UsercenterComponent.isLoginLiveData.value == true) {
chain.proceedSync()
} else {
showLogin()
Result.resultError(-3, "拦截, 进入登录页")
}
}
}
END
更多详情在 GitHub
欢迎感兴趣的朋友提供反馈和建议。
作者:WJ
来源:juejin.cn/post/7287817398315892777
来源:juejin.cn/post/7287817398315892777