标签:
EventBus使得组件之间的发布-订阅式的通信,而无需组件与另一个(因此要注意对方的),明确登记。它的设计完全使用明确的登记,以取代传统的Java过程中的事件分发。它是不是一个通用的发布-订阅系统中,也不旨在用于进程间通信。
//类通常由注册 地方在初始化过程中 eventBus 。注册(新 EventBusChangeRecorder ()); //要晚得多 公共 无效changeCustomer () { 的ChangeEvent 事件 = getChangeEvent (); eventBus 。后(事件); }
将现有的EventListener基于系统使用的EventBus容易。
侦听事件的特定味道(比如,一个CustomerChangeEvent)...
注册您的侦听器方法的事件生产者...
要收听和检测共出动,没有听众的事件...
为了跟踪监听到你的事件?
派遣一个事件监听器...
该EventBus系统代码中使用下列术语来讨论事件分发:
事件 | 可任意物体贴到一个总线。 |
认购 | 登记的动作侦听器与EventBus,使得它的处理方法将获得的事件。 |
倾听者 | 任何希望接收事件,暴露的对象处理方法。 |
处理方法 | 该公共方法EventBus应该使用提供发布事件。处理方法的标志是订阅注解。 |
发布事件 | 使得事件提供给任何听众通过EventBus。 |
EventBus不指定你如何使用它; 没有什么不必单独停止你的应用程序EventBus情况下,为每个组件,或者使用单独的实例来分离上下文或主题活动。这也使得它琐碎的建立和拆除EventBus在您的测试对象。
当然,如果你想有一个过程性的EventBus单身,没有什么从做这种方式阻止你。只需您的容器(如吉斯)创建EventBus作为一个单身在全局范围内(或藏在一个静态字段,如果你到诸如此类的事情)。
总之,EventBus是不是单身,因为我们宁愿不作出这样的决定你。使用它,你怎么样。
是的,使用EventBus.unregister,但我们发现,只需要很少:
我们认为事件总线的@Subscribe注释就像明确地传达你的意图是实现一个接口(或者更左右),同时使你自由,无论你希望将事件处理方法,并给他们的意图展现的名字。
传统的Java活动使用监听器接口通常运动只有极少数的方法 - 通常是一个。这具有许多缺点:
在干净实施这一困难已经引起了一种模式,在Swing应用程序中特别常见,用微小的匿名类来实现事件监听器接口。
比较这两种情况:
class ChangeRecorder { void setCustomer ( Customer cust ) { cust . addChangeListener ( new ChangeListener () { public void customerChanged ( ChangeEvent e ) { recordChange ( e . getChange ()); } }; } }
与
//类通常由注册container. class EventBusChangeRecorder { @Subscribe public void recordCustomerChange ( ChangeEvent e ) { recordChange ( e . getChange ()); } }
其目的是在第二种情况下居然清晰的:有较少的噪声码,和事件处理程序有一个明确的和有意义的名字。
有人提出了一个通用的处理程序<T>接口EventBus听众。这将运行与Java的使用类型擦除的,更何况在可用性问题的问题。
比方说,界面看起来像下面这样:
接口 处理器< 牛逼> { 无效的handleEvent (牛逼事件); }
由于擦除,没有任何一个类可以用不同类型的参数实现的通用接口不止一次。这是一个巨大的倒退,从传统的Java事件,在那里即使的actionPerformed和的keyPressed都不是很有意义的名字,至少可以实现两个方法!
有些人吓坏了约EventBus的寄存器(对象)和后期(对象)的方法“使用的对象类型。
对象在这里使用一个很好的理由:事件总线库的地方在任您事件侦听器的类型没有限制(如寄存器(对象))或事件本身(在后(对象))。
事件处理方法,在另一方面,必须明确声明其参数类型 - 所需的事件类型(或它的超类型之一)。因此,寻找引用的事件类将立即查找所有处理方法该事件,并重新命名的类型会影响视野内的IDE(以及创建活动的任何代码)的所有处理方法。
这是真的,你可以重命名你@Subscribed随意事件处理方法; 事件总线不会停止这样或做任何事情来传播重命名,因为,到事件总线,你的处理方法的名称是无关紧要的。但是这是你的重构工具是什么-即直接调用,当然会受你的重命名的方法测试代码。我们认为这是一个特点,不是一个错误:能重命名处理方法的意愿让你做自己的意思更清晰。
什么都没有。
事件总线的设计与容器和模块系统集成,与吉斯作为典型例子。在这种情况下,它的方便的容器/工厂/环境下通过每个创建的对象到EventBus的寄存器(对象)的方法。
这样,通过容器/工厂/环境创建的任何对象都可以通过简单地暴露处理方法挂接到系统的事件模型。
可以通过Java的类型系统明确地检测出任何问题。例如,定义一个处理方法不存在的事件类型。
紧随调用寄存器(对象),正在注册的侦听器检查的良好性,其处理方法。具体来说,标有任何方法@Subscribe必须只有一个参数。
任何违反此规则将导致抛出:IllegalArgumentException抛出。
(此检查可以移动使用APT,一个解决方案,我们正在研究编译时间。)
如果没有注册的侦听器组件发布事件,它可能会指示错误(通常是你错过了一个指示@Subscribe注释,或没有加载监听组件)。
(请注意,这并不一定表明有问题的。有很多情况下,一个应用程序会故意忽略发布的事件,特别是如果事件是从你无法控制的代码来了。)
为了处理这些事件,注册一个处理方法为DeadEvent类。每当EventBus接收到一个事件,没有注册的处理程序,它会变成一个DeadEvent,并通过它自己的方式-让你登录,或以其他方式收回。
因为你的监听类处理方法都是正常的方法,你可以简单地从你的测试代码中调用它们来模拟EventBus。
EventBus是专门用来对付一大类用例真的,真的很好。我们宁愿打在要害大多数用例在所有用例做体面。
此外,使得EventBus扩展-和使得它非常有用和生产上延伸,而仍允许自己作出补充到芯EventBus API,它不与任何的扩展的冲突-是一个极其困难的问题。
如果你真的,真的需要魔法的事情X,即EventBus目前无法提供,你应该提交一个问题,然后设计自己的选择。
标签:
原文地址:http://blog.csdn.net/dulizhi1991/article/details/43734341