0%

EventBus——the No.1 Open Source Event Library for Android

EventBus is an open-source library for Android using the publisher/subscriber pattern for loose coupling. EventBus enables central communication to decoupled classes with just a few lines of code – simplifying the code, removing dependencies, and speeding up app development.

EventBus…

  • simplifies the communication between components
    • decouples event senders and receivers
    • performs well with Activities, Fragments, and background threads
    • avoids complex and error-prone dependencies and life cycle issues
  • makes your code simpler
  • is fast
  • is tiny (~50k jar)
  • is proven in practice by apps with 100,000,000+ installs
  • has advanced features like delivery threads, subscriber priorities, etc.

EventBus in 3 steps

Step 1: Define events

Events are POJO (plain old Java object) without any specific requirements.

1
2
3
4
5
6
7
8
public class MessageEvent {

public final String message;

public MessageEvent(String message) {
this.message = message;
}
}

Step 2: Prepare subscribers

Subscribers implement event handling methods (also called “subscriber methods”) that will be called when an event is posted. These are defined with the @Subscribe annotation.

Note that with EventBus 3 the method name can be chosen freely (no naming conventions like in EventBus 2).

1
2
3
4
5
6
7
8
9
10
11
// This method will be called when a MessageEvent is posted (in the UI thread for Toast)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}

// This method will be called when a SomeOtherEvent is posted
@Subscribe
public void handleSomethingElse(SomeOtherEvent event) {
doSomethingWith(event);
}

Subscribers also need to register themselves to and unregister from the bus. Only while subscribers are registered, they will receive events. In Android, in activities and fragments you should usually register according to their life cycle. For most cases onStart/onStop works fine:

1
2
3
4
5
6
7
8
9
10
11
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}

@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}

Step 3: Post events

Post an event from any part of your code. All currently registered subscribers matching the event type will receive it.

1
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

Read the full getting started guide.

Add EventBus to your project

Please ensure that you are using the latest version by checking here

Gradle:

1
compile 'org.greenrobot:eventbus:3.0.0'

Maven:

1
2
3
4
5
<dependency>
<groupId>org.greenrobot</groupId>
<artifactId>eventbus</artifactId>
<version>3.0.0</version>
</dependency>

Or download EventBus from Maven Central

For more details on EventBus please check EventBus’ website. Here are some direct links you may find useful:

Features

Documentation

Changelog

FAQ

How does EventBus compare to other solutions, like Otto from Square? Check this comparison.

License

Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)

EventBus binaries and source code can be used according to the Apache License, Version 2.0.

More Open Source by greenrobot

greenrobot-common is a set of utility classes and hash functions for Android & Java projects.

greenDAO is an ORM optimized for Android: it maps database tables to Java objects and uses code generation for optimal speed.

Follow us on Google+ or check our homepage to stay up to date.

EventBus源码分析[3]

EventBus的好处是显而易见的,完全解耦了请求链之间的关系,避免了请求者被长持有,又比广播更轻量,比LocalBroadcast则更强大,接口也简单实用。缺点的话,像是各种Event的定义是一个工作量。

EventBus, otto, LocalBroadcast的选择[4]

  1. greenrobot的EventBus
  2. square的otto
  3. android support包里提供的LocalBroadcast

三者都是类似订阅/发布的模式,降低了耦合度。与callback比起来,这种事件总线的模式使得两个类没有直接的依赖关系,对架构来说进行了解耦,把双向依赖变成了单向依赖,在大型项目中尤其显得重要。

Why publish/subscribe

一方面,callback很容易产生内存泄露,如I/O、网络操作持有了Activity/Fragment的引用,导致不能及时释放,而团队中也很难保证每个成员都足够优秀在写callback的时候能使用弱引用或静态变量。相比起来订阅/发布者模式则比较简单,直接在BaseActivity的onDestroy释放掉,避免了可能的坑。

另外,从可扩展性、可维护性的角度来说,callback也更局限,比如以前某个接口是告诉上层网络数据拉回来了,现在我们希望扩展,这个接口也支持直接告诉上层数据库拉回来了,向上层屏蔽数据来源,如果用callback,则在一次回调结束后,没有办法再次进行回调了。页面必须自己去处理数据来源和拉数据的逻辑。

虽然有些over-architect的嫌疑,但是Android-CleanArchitecture 确实是一种很clean的architecture,而其也正是通过观察者/订阅者模式来实现了单向依赖。

比较

EventBus的github上就有其和otto的比较: EventBus vs Otto

总的来说,两者功能差的不多,otto多了Event producers (e.g. for coding cached events),而EventBus则多了各种线程的处理、订阅者继承、sticky event等。

但从性能来说,由于otto使用了基于反射的annotation,而和EventBus产生了一定的差距(内部应该还有一些其他问题导致的性能差异,待研究)

三者都不支持跨进程,LocalBroadcast内部其实使用的是Handler,所以其实更像是一个utils类。

如果要做选择的话,LocalBroadcast更轻量,otto相比起api更好用,而EventBus则拥有很棒的线程模型,我投EventBus一票,因为onEvent的各种线程回调真的很方便。

Android Clean Architecture[5]

Clean architecture

Architectural approach

Architectural reactive approach

应用MVP模式写出可维护的优美Android应用[6]

MVP是什么

MVP是MVC模式的一个衍生物,可以简单看下图。在MVP模式中,V层完全和M层(在Android中可能是Model、DAO、或者通用的business logic)分开。在中间用P层分隔,从而把数据有关和UI有关完全分离开。

主流的MVP又有两种实现方式

1)Activity、Fragment、View直接作为V层。Presenter通过继承被视图层实例化或者通过注入得到。这样Presenter在理想状态下可以完全和Android分离,也剥离了activity的那些生命周期。

2)Activity和Fragment作为P层,另外单独创建一个V层类,持有Activity里面的各种view,并提供接口让Activity调用来更新界面。

为了让V层和P层解耦,通常P层对V层的持有是通过interface的。

一个完整的mvp事件流可以是

个人心得

不要把presenter当做OnClickListener,View才是来处理用户输入和给予反馈的,presenter不应该知道view内部的逻辑来判断点击某个按钮后做出什么相应。一个简单的判断某个逻辑是否属于presenter的方法是,如果view层不是android,而是java桌面应用,那你的presenter层是不是还能不做更改地work。

view层只做presenter层让你做的,比如上图view层用户点了一个按钮,View调用了presenter.loadUsers,presenter一边在background thread去getUsers,一边调用了view.showLoading(),view层不该自说自话地showLoading。不过如何showLoading,比如展示怎么样的动画,那就是view层的内部矛盾了。

一个很大的好处,就是通过MVP,异步变得很清晰,view层的东西完全是主线程的,只需要等着presenter调就行了。

Reference

[1]EventBus
[2]How to get started with EventBus in 3 steps
[3]EventBus源码分析
[4]EventBus, otto, LocalBroadcast的选择
[5]Android-CleanArchitecture
[6]应用MVP模式写出可维护的优美Android应用

欢迎关注我的其它发布渠道