GitHub

Gitee

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
欢迎感兴趣的朋友供给反应和建议。