使用Event Bus模式解耦Android App组件间通信

转载 2013年12月05日 20:20:52

场景描述

当一个Android应用功能越来越多的时候,保证应用的各个部分之间高效的通信将变得越来越困难。

在应用中的多个地方,控件经常需要根据某个状态来更新他们显示的内容。这种场景常见的解决方式就是定义一个接口,需要关注该事件的控件来实现这个接口。然后事件触发的地方来注册/取消注册这些对该事件感兴趣的控件。

例如,陌陌依赖手机位置信息来获取附近的用户,所以在位置更新管理器(MmLocationManager)中定义了一个接口来监听位置更新的事件(MmLocationListener):

1
2
3
interface MmLocationListener {
 void onLocationChanged(Location location);
}

然后在应用的各个需要响应该事件的地方来实现上面的接口,然后在位置更新管理器(MmLocationManager)中注册/取消注册事件监听接口的实现类:

1
mLocationManager.get().register(this);

当不在需要监听的时候,取消注册

1
mLocationManager.get().unregister(this);

问题

上面的解决方案是没问题的,但是不是理想方案。每个控件实现这个接口,导致这些控件和位置管理器注册强耦合在一起。这还意味着,当单元测试的时候,您需要模拟(mocked)位置管理器来生成位置更新事件。

随着应用功能的增加,需要监听的事件越来越多,而越来越多的控件需要监听不同的事件,则导致越来越多的控件需要注册到各种事件管理器上:

1
2
3
4
5
6
// 代码开始变得无法控制…
mLocationManager.get().register(this);
userAuthenticator.get().register(this);
settingsManager.get().register(this);
syncManager.get().register(this);
configurationMonitor.get().register(this);

注意:上面的每个事件的注册,都要实现对应的时间更新接口。

注册和取消注册这些事件慢慢的会变得越来越难以管理。导致测试越来越困难,并将导致开发者的效率越来越低,同时在您的应用中越来越容易引入各种奇怪的Bug。

解决方案

为了找出该问题的优雅解决方案,从一个意想不到的的地方借鉴点经验 — Swing应用。 Event Bus模式 — 也被称为Message Bus或者发布者/订阅者(publisher/subscriber)模式 — 可以让两个组件相互通信,但是他们之间并不相互知晓。

和需要注册各个事件的监听器相比,一个组件现在只用在Event Bus上注册一次即可:

1
bus.register(this);

上面的注册告诉Event Bus我们现在希望接收各个事件的更新。 然后Bus检测该类中每个带有@Subscribe注解的函数,当相关的事件发生的时候就调用这些带有注解的函数。

上面示例中的位置监听功能,不用实现位置监听接口和里面的函数了,只需要提供一个带有@Subscribe注解的函数即可:

1
2
3
4
@Subscribe
public void locationChanged(LocationChangedEvent event) {
   // TODO React to location change.
}

现在Event Bus会把所有的LocationChangedEvent 事件都发送给上面的函数。

现在 MmLocationManager 类不用注册监听器了,当位置改变的时候 只需要向Event Bus发布事件即可:

1
bus.post(new LocationChangedEvent(37.892818, -121.772608));

这样 组件间相互解耦了,而单元测试也变得简单了。任何事件都可以发布给Event Bus,然后Event Bus会找到对该事件感兴趣的函数来调用。

注意:您也许已经发现该模式在Android上层也存在 — Intent系统就是这样设计的!

下面介绍两个Android系统的Event Bus模式类库。

Otto — Android系统的Event Bus类库

OttoSquare公司在他们应用中使用的Event Bus实现。从Guava中演变而来,并且专注于Android平台。

通过使用Otto,Square公司的应用组件间不紧密耦合了,单元测试也更加容易了。

您可以通过Otto项目的主页来了解更多内容或者查看Otto项目的源代码

EventBus — Android系统的Event Bus类库

EventBus http://greenrobot.de 出品的另外一个Event Bus类库,功能稍微多一点。

在后面的文章中将会分别介绍如何使用Otto和EventBus。



Read more: http://blog.chengyunfeng.com/?p=449#ixzz2mbPmvzb3

Android组件化之模块解耦和通信

针对Android组件化,组件间解耦和通信而创建的一个轻量级的框架
  • u010014658
  • u010014658
  • 2016年12月22日 20:07
  • 4945

Android 解耦方法 ~~~ 事件总线

一.它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使我们的代码更加简洁,耦合性更低,提升了我们的代码质量。 二.设计模式:观察者模式。 三...
  • u012247772
  • u012247772
  • 2016年09月17日 13:03
  • 506

【android】使用Event Bus模式解耦Android App组件间通信

场景描述 当一个Android应用功能越来越多的时候,保证应用的各个部分之间高效的通信将变得越来越困难。 在应用中的多个地方,控件经常需要根据某个状态来更新他们显示的内容。这种场景常见的解...
  • u011494050
  • u011494050
  • 2014年10月24日 22:35
  • 927

使用EventBus解耦,简化组件通信

使用了EventBus后不同界面不同组件之间的信息交换将会变得非常容易,使用起来也非常简单,暂时没有发现什么副作用 注意这里使用的是greenrobot的EventBus,包名为 de.greenro...
  • shihui512
  • shihui512
  • 2016年03月10日 21:43
  • 422

vue中的event bus非父子组件通信

有时候非父子关系的组件也需要通信。在简单的场景下,使用一个空的Vue实例作为中央事件总线: 有时候非父子关系的组件也需要通信。在简单的场景下,使用一个空的 Vue 实例作为中央事件总线: ...
  • qq_24122593
  • qq_24122593
  • 2016年12月21日 18:04
  • 8519

项目解耦必备-EventBus的详细讲解(一)

很早之前,就想写一篇关于EventBus使用的文章,一直没有时间,最近项目不太忙,抽出一些时间把之前的项目中的技术沉淀一下,抽取出一些东西写成文章与大家分享一下。 在做项目的时候,难免会碰到一个问题,...
  • u014752325
  • u014752325
  • 2016年03月23日 14:01
  • 1200

使用EventBus轻松实现组件间通信

我之前写过一篇文章“Android开发之局部广播的使用”,地址:http://blog.csdn.net/jarchie520/article/details/71434833,在这篇文章里面使用的方...
  • JArchie520
  • JArchie520
  • 2017年11月28日 16:00
  • 72

ios业务模块间互相跳转的解耦方案

一个app通常由许多个模块组成,所有模块之间免不了会相互调用,例如一个读书管理软件,可能会有书架、用户信息、图书详情等等模块,从用户信息-我读的书中,可以打开图书详情。而在图书详情-所在书架,又可以打...
  • cuibo1123
  • cuibo1123
  • 2016年03月30日 17:58
  • 6535

Android组件间通信库EventBus学习

项目地址:  https://github.com/greenrobot/EventBus
  • djun100
  • djun100
  • 2014年04月15日 15:59
  • 47569

android Event Bus解耦android模块

当一个Android应用功能越来越多的时候,保证应用的各个部分之间高效的通信将变得越来越困难。如何优雅地解决这个问题?这时候,就需要使用到EventBus。 EventBus是GreenRobot出品...
  • MINGZHNGLEI
  • MINGZHNGLEI
  • 2016年05月17日 17:48
  • 190
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用Event Bus模式解耦Android App组件间通信
举报原因:
原因补充:

(最多只允许输入30个字)