GWT - MVP事件总线。多个处理程序被创建

时间:2012-12-06 22:56:40

标签: java gwt mvp event-bus

我正在使用我继承的大型应用程序,并且遇到了一些最佳实践问题。

每次用户导航到“我们的客户编辑”页面时,都会创建一个新的演示者,并设置一个视图。有一个主要的客户编辑演示者和一个主视图。主视图中还有子视图,由主演示者的子演示者使用。在子演示者中,我在事件总线上注册事件处理程序。

我遇到的问题是,当第二次导航到联系人编辑器时,会再次创建演示者,并再次注册这些事件。现在,当一个事件发生时,它会被处理两次,每个presenter实例一次。

演示者不会被变量保留,但子视图会被主视图引用。可能是视图中的这个引用是否阻止事件处理程序被删除?我的印象是,如果该对象被垃圾收集,将删除事件处理程序。如果不是这种情况,我应该从事件总线取消注册这些事件处理程序吗?

更新: 演示者不是垃圾收集者。 如果我可以修改代码以在不再需要这些演示者时删除对这些演示者的所有引用,是否会收集它们,因此会删除事件处理程序吗?

2 个答案:

答案 0 :(得分:5)

ResettableEventBus是专门为此设计的 - 不是给Presenter一个全局事件总线,而是将该事件总线包装在Resettable版本中。然后,当该演示者关闭时,无论谁给它该事件总线重置它,从而清理它可能已添加的所有处理程序。

这就是如何管理GWT活动/场所框架中的活动以防止它们泄露。

另一种选择 - 为每个Presenter提供一个类似'stop()'或'release()'的方法,表明它是最重要的,它应该自行消除 - 取消正在进行的RPC调用,删除对话框,取消事件处理程序。如上所述,Activity api有一个方法来表明它即将停止,并且它已经停止并且应该清理。

提供两者可以很容易地使用全局事件总线不会出错,并且仍然可以解决更细粒度的问题(长时间运行的RPC调用),但问题可以通过任一解决方案解决。

答案 1 :(得分:0)

事件处理程序是单独的对象实例,它们是根据EventBus中的某种集合设置和存储的。您的演示者只是创建它们并将它们传递给EventBus,因此处理程序仍会在演示者的生命周期之外被引用(这就是它们继续运行的原因)。演示者可能没有被垃圾收集,因为处理程序仍然可以引用它们或它们的字段。

创建一个新的演示者每次都会在您检测到时再次添加处理程序,因此解决方案是在实例化新演示者之前清除现有处理程序,或者跟踪它们并在它们'时添加新处理程序'已经添加了。

我采用的方法是重新使用屏幕级View / Presenter实例,并在重新进入时重置其状态。这也有助于提高性能。演示者还会跟踪他们添加到EventBus的所有处理程序的HandlerRegistration实例。

我不知道Colin提到的ResettableEventBus,但这听起来也是一个很好的解决方案。