一个全新的 Android 组件化通信工具

GitHub
Gitee

ComponentBus 这个项目已经内部使用了一段时间, 经过几次迭代.

他非常小巧, 且功能强大, 并且配有 IDEA 插件作为辅助.

ComponentBus 利用 ASM、KSP, 使组件间的通信变得简单且高效.

第一步组件间通信

新建一个 Module, 我们给他添加一个接口

kotlin 复制代码
@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

kotlin 复制代码
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

拦截器

全局拦截器

kotlin 复制代码
/**  
 * 全局日志拦截器  
 */  
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")  
    }  
}

普通拦截器

kotlin 复制代码
/**  
 * 判断是否是登录的拦截器  
 * 未登录会进入登录页面  
 */  
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

欢迎感兴趣的朋友提供反馈和建议。

相关推荐
段娇娇3 小时前
Android jetpack LiveData(一)使用篇
android·android jetpack
XiaoLeisj3 小时前
Android Jetpack 页面架构实战:从 LiveData、ViewModel 到 DataBinding 的生命周期管理与数据绑定
android·java·架构·android jetpack·livedata·viewmodel·databinding
似水明俊德7 小时前
15-C#
android·开发语言·c#
阿拉斯攀登7 小时前
第 19 篇 驱动性能优化与功耗优化实战
android·驱动开发·瑞芯微·嵌入式驱动·安卓驱动
91刘仁德8 小时前
C++ 内存管理
android·c语言·数据结构·c++·经验分享·笔记·算法
小强开学前9 小时前
自定义 Drawable 实现任意高度纯圆角背景及玻璃效果
android
秃了也弱了。9 小时前
ElasticSearch:优化案例实战解析(持续更新)
android·java·elasticsearch
恋猫de小郭9 小时前
Kotlin 在 2.0 - 2.3 都更新了什么特性,一口气带你看完这两年 Kotlin 更新
android·前端·flutter
墨狂之逸才10 小时前
React Native 移动项目目录导致的 Android 编译失败问题及解决方案
android·react native
feng一样的男子10 小时前
住在手机里的“小龙虾” (OpenClaw):接入本地模型,解决记忆“装死”顽疾
android·ai·智能手机·openclaw