Kotlin开发第七天,EventBus组件间通信

完整代码Gitee地址:kotlin-demo: 10天Kotlin开发计划

第七天学习内容代码:Chapter7

EventBus-Kotlin 

官方地址:https://github.com/greenrobot/EventBus

//build.gradle -> dependencies 引入
implementation 'org.greenrobot:eventbus:3.2.0'

EventBus原理

EventBus 是基于观察者模式,核心是事件。通过事件的发布和订阅实现组件之间的通信,EventBus默认是一个单例存在,在Java中还需要使用Synchronized来保证线程安全。

通俗来讲,EventBus通过注册将所有订阅事件的方法储存在集合中,当有事件发布的时候,根据某些规则,匹配出符合条件的方法,调用执行,从而实现组件间的通信。

发布的事件相当于被观察者,注册的对象相当于观察者,被观察者和观察者是一对多的关系。当被观察者状态发生变化,即发布事件的时候,观察者对象将会得到通知并作出响应,即执行对应的方法。

EventBus使用

使用Kotlin版本的EventBus,更方便的实现UI间通信,高性能、简单而强大,最主要是使用框架更为便捷;  

举个栗子:

  • 界面A->界面B 我们可以使用Intent传递
  • 界面B->界面A 我们也可以使用onActivityResult接收
  • 界面A->界面B->界面C,或者界面C->界面A 再使用Intent传递就太绕了

接收方必须注册与注销,在主线程订阅接收,代码如下:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //注册,重复注册会导致崩溃
        EventBus.getDefault().register(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        //注销,有注册就必须注销
        EventBus.getDefault().unregister(this)
    }

   //接收消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: String) {
        if (event == "message") {
            Toast.makeText(this, "收到订阅,主界面已更新", Toast.LENGTH_SHORT).show()
            button7.text = "①主界面更新"
        }
    }

    //接收消息
    @SuppressLint("SetTextI18n")
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: MessageEvent) {
        when (event.type) {
            MessageType.ShowLog -> {
                Log.e(tag, "onMessageEvent: " + event.getString())
            }
            MessageType.ShowToast -> {
                Toast.makeText(this, "onMessageEvent: " + event.getString(), Toast.LENGTH_SHORT).show()
                button7.text = "②" + event.getString()
            }
        }
    }

 发送方,代码如下:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_learn7)
        val title: TextView = findViewById(R.id.tv_title)
        title.text = "组件间通信"

        val butTip1: Button = findViewById(R.id.but_tip1)
        butTip1.setOnClickListener {
            EventBus.getDefault().post("message")
        }

        val butTip2: Button = findViewById(R.id.but_tip2)
        butTip2.setOnClickListener {
            EventBus.getDefault().post(MessageEvent(MessageType.ShowLog).put("打印日志"))
            EventBus.getDefault().post(MessageEvent(MessageType.ShowToast).put("组件间通信"))
        }
    }

 创建发送数据模型MessageEvent

private const val KEY_INT = "key_int"
private const val KEY_STRING = "key_string"
private const val KEY_BOOL = "key_bool"
private const val KEY_SERIALIZABLE = "key_serializable"
private const val KEY_PARCELABLE = "key_parcelable"


data class MessageEvent(var type: MessageType) {

    var bundle = Bundle()

    fun put(value: Int): MessageEvent {
        bundle.putInt(KEY_INT, value)
        return this
    }

    fun put(value: String): MessageEvent {
        bundle.putString(KEY_STRING, value)
        return this
    }

    fun put(value: Boolean): MessageEvent {
        bundle.putBoolean(KEY_BOOL, value)
        return this
    }

    fun put(value: Serializable): MessageEvent {
        bundle.putSerializable(KEY_SERIALIZABLE, value)
        return this
    }

    fun put(value: Parcelable): MessageEvent {
        bundle.putParcelable(KEY_PARCELABLE, value)
        return this
    }

    fun put(key: String, value: Int): MessageEvent {
        bundle.putInt(key, value)
        return this
    }

    fun put(key: String, value: String): MessageEvent {
        bundle.putString(key, value)
        return this
    }

    fun put(key: String, value: Boolean): MessageEvent {
        bundle.putBoolean(key, value)
        return this
    }

    fun put(key: String, value: Serializable): MessageEvent {
        bundle.putSerializable(key, value)
        return this
    }

    fun put(key: String, value: Parcelable): MessageEvent {
        bundle.putParcelable(key, value)
        return this
    }

    //===============================================================

    fun getInt(): Int {
        return bundle.getInt(KEY_INT)
    }

    fun getString(): String? {
        return bundle.getString(KEY_STRING)
    }

    fun getBoolean(): Boolean {
        return bundle.getBoolean(KEY_BOOL)
    }

    fun <T : Serializable> getSerializable(): Serializable {
        return bundle.getSerializable(KEY_SERIALIZABLE) as T
    }

    fun <T : Parcelable> getParcelable(): T? {
        return bundle.getParcelable<T>(KEY_PARCELABLE)
    }

    fun getInt(key: String): Int {
        return bundle.getInt(key)
    }

    fun getString(key: String): String? {
        return bundle.getString(key)
    }

    fun getBoolean(key: String): Boolean {
        return bundle.getBoolean(key)
    }

    fun <T : Serializable> getSerializable(key: String): Serializable {
        return bundle.getSerializable(key) as T
    }

    fun <T : Parcelable> getParcelable(key: String): T? {
        return bundle.getParcelable<T>(key)
    }

}

enum class MessageType {
    ShowToast,
    ShowLog,
}

效果展示:

事件总线功能

greenrobot 的 EventBus 的独特之处在于它的功能:

  • 简单而强大:  EventBus 是一个微型库,其 API 非常容易学习。然而,通过解耦组件,您的软件架构可能会受益匪浅:订阅者在使用事件时并不了解发送者。
  • 实战测试: EventBus 是最常用的 Android 库之一:数以千计的应用程序使用 EventBus,包括非常流行的应用程序。超过 10 亿次应用安装不言而喻。
  • 高性能:尤其是在 Android 上,性能很重要。EventBus 进行了大量分析和优化;可能使其成为同类中最快的解决方案。
  • 方便的基于注解的 API  (不牺牲性能)只需将 @Subscribe 注解放到您的订阅者方法中即可。由于注释的构建时索引,EventBus 不需要在您的应用程序运行时进行注释反射,这在 Android 上非常慢。
  • Android 主线程传递:在与 UI 交互时,EventBus 可以在主线程中传递事件,而不管事件是如何发布的。
  • 后台线程传递:如果您的订阅者执行长时间运行的任务,EventBus 还可以使用后台线程来避免 UI 阻塞。
  • 事件和订阅者继承:在 EventBus 中,面向对象的范式适用于事件和订阅者类。假设事件类 A 是 B 的超类。发布的 B 类事件也将发布给对 A 感兴趣的订阅者。类似地考虑订阅者类的继承。
  • 零配置: 您可以立即开始使用可从代码中的任何位置使用的默认 EventBus 实例。
  • 可配置: 要根据您的要求调整 EventBus,您可以使用构建器模式调整其行为。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

peacejay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值