之前学习了Rxjava(RxJava学习笔记),但是一直找不到使用它的地方。最近做项目的时候遇到需要使用eventbus的时候,突然想起来Rxjava的一个拓展面就是Rxbus,果断用来试试

下一篇博文:RxJava实现原理探索

什么是Eventbus

EventBus定义:是一个发布 / 订阅的事件总线。
这么说应该包含4个成分:发布者,订阅者,事件,总线。
那么这四者的关系是什么呢?
很明显:订阅者订阅事件到总线,发送者发布事件。

总结一下就是:我订阅你,你遇到事情了,发送事件,或者理解为更新动态,我就收到消息。

常用的地方

Eventbus和Rxbus常用于组件间信息的交换与通知,避免采用广播以及使用一大堆接口来实现。

使用的地方以本次项目来举例:
一个商城界面,包含一个RecyclerView和LinearLayout,LinearLayout中是一个购物篮信息,也就是美团那种。当点击RecyclerView中的按钮时,商品被添加,LinearLayout中的商品总价应该发生变化。而这时候就到了使用Eventbus或者Rxbus的时候了。
为了增加商品总价,常见的方法有这几种:

  1. 在创建adapter的时候将LinearLayout的对象一并传入,以此可以更改LinearLayout中的TextView
  2. 设置广播事件。添加商品-》发送广播-》处理广播
  3. 设置接口。添加商品-》触发接口
  4. 使用观察者模式。也就是Eventbus以及Rxbus实现的功能。

上面的四种方式,第一种差评,可以直接排除。第二种和第三种倒是可以,但是这种事件多了之后就会产生一大堆接口,维护起来很麻烦。
因此,在这里就可以使用Eventbus或者Rxbus了。
而Rxjava相对于Eventbus来说更加的好用,因为它不止这个功能,还可以避免compile一大堆其余的依赖

使用Rxjava实现Rxbus代替eventbus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.screform.mmd.utils;

import android.os.Bundle;

import rx.Observable;
import rx.subjects.PublishSubject;
import rx.subjects.SerializedSubject;
import rx.subjects.Subject;

/**
* RxBus
* Created by lizhongquan on 16-1-20.
*/
public class RxBus {

private final Subject<Object, Object>
rxBus = new SerializedSubject<>(PublishSubject.create());

private RxBus() {

}

public static RxBus getInstance() {
return RxbusHolder.instance;
}

public static class RxbusHolder{
private static final RxBus instance = new RxBus();
}

public void send(Bundle o) {
rxBus.onNext(o);
}

public Observable<Object> toObserverable() {
return rxBus;
}
}

使用
在被订阅的地方

1
2
3
4
// 利用bundle传值
Bundle bundle = new Bundle();
bundle.putString("eventname", "addOrderInfoGoods");
RxBus.getInstance().send(bundle);

订阅者
首先使用map进行类型转换,将Object类型转换为Bundle类型
之后在onNext中进行处理(这里使用一个参的new Action1替换)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* RxBus
*/
private void operateBus() {
RxBus.getInstance().toObserverable()
.map(new Func1<Object, Bundle>() {
@Override
public Bundle call(Object o) {
return (Bundle) o;
}
})
.subscribe(new Action1<Bundle>() {
@Override
public void call(Bundle bundle) {
if (bundle.getString("eventname").equals("showLinearLayoutBuyOK")) {
showLinearLayoutBuyOK(bundle);
}
}
});

这样的话就完成了整个订阅与处理事件。
另外,一旦订阅者订阅了某个事件,就一定要记得取消订阅,不然会造成内存泄露。一般是在onStop或者是onPause中。

取消订阅
-
可以利用Subscription rxsub = Rxbus.getInstance()……….
在onStop或者是onPause中使用rxsub.unsubscribe()方法就可以取消了
而这个rxsub至于是生成一个全局的还是通过其他的方式来获取或者是取消就可以根据自己的需要来设置了,一定要注意避免内存泄露,对于手机内存小的积累一下很容易就OOM了


可添加的功能
-
还有一个就是关于订阅事件的分发问题,现在是利用Bundle来传递事件名,其实这样不好,因为这样的话所有的订阅者都会收到通知。可以在Rxbus中添加一个过滤器,这样就可以让指定订阅者收到。最近由于事情太多,以后有需要的时候再更新吧