RxBus
转载自: https://blog.csdn.net/qq_34015596/article/details/86477220
我们传统事件消息发布是使用EventBus来实现,它的工作机制类似于观察者模式,通过通知者去注册观察者,最后由通知者向观察者发布消息,在Android开发中,使用EventBus可以解耦AsyncTask,Handler,Thread,Broadcast等各个组件,还可以用于Fragment之间的通信。但是EventBus内部是基于反射来获取订阅方法,订阅事件,订阅者,因此性能上有所影响,我们可以使用Rxjava来实现EventBus的相关方法,代码量很少,使用简单,性能较高。使用Relay新增了异常处理,加入了粘性事件,通常使用EventBus需要先注册好事件才能使用。现在可以这样使用,某一时间还没来得及注册,但是已经发送了,只要注册成功后,订阅者再进行消费。因为粘性事件用途广泛,在App开发中,App初始化要做很多事情,比如获取App的配置接口,做一些耗时的初始化工作。为了让App能够快速进入主界面,可以在App的Application中使用事件总线来发送一个粘性事件,在主界面中注册好粘性事件。这样App无需在启动页中做很多初始化工作,从而能够快速进入页面,也不会耽误初始化。
我们先来实现一个简单版的EventBus:
public class RxBus {
private Subject<Object> mBus;
private RxBus() {
mBus=PublishSubject.create().toSerialized();
}
public static RxBus get() {
return Holder.BUS;
}
public void post(Object obj) {
mBus.onNext(obj);
}
public <T> Observable<T> toObservable(Class<T> tClass) {
return mBus.ofType(tClass);
}
public Observable<Object> toObservable() {
return mBus;
}
public boolean hasObservers() {
return mBus.hasObservers();
}
private static class Holder {
public static final RxBus BUS = new RxBus();
}
}
简单使用:
在MainActivity中订阅事件:
mCompositeDisposable.add(RxBus.get().register(Fragment1Event.class, new Consumer<Fragment1Event>() {
@Override
public void accept(Fragment1Event fragment1Event) throws Exception {
mFragment2.getTv().setText("fragment2已经收到"+fragment1Event.msg);
String str = null;
System.out.println(str.substring(0));
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable t) throws Exception {
Log.d("22",t.getMessage());
}
}));
在Fragment1中发布事件:
RxBus.get().post(fragment1Event);
我们使用Relay来实现最后加强版带有Sticky事件
/\*\*
\* 发送sticky事件
\*
\* @param event
*/
public void postSticky(Object event) {
synchronized (mStickyEventMap) {
mStickyEventMap.put(event.getClass(), event);
}
bus.accept(event);
}
mStickyEventMap会把Sticky事件先缓存起来, mStickyEventMap是一个ConcurrentHashMap,所以他是线程安全的
/\*\*
\* 转换成Observable对象
\*
\* @param eventType
\* @param <T>
\* @return
*/
public <T> Observable<T> toObservableSticky(final Class<T> eventType) {
synchronized (mStickyEventMap) {
Observable<T> observable = bus.ofType(eventType);
final Object object = mStickyEventMap.get(eventType);
if (object != null) {
return observable.mergeWith(Observable.create(new ObservableOnSubscribe<T>() {
@Override
public void subscribe(ObservableEmitter<T> emitter) throws Exception {
emitter.onNext(eventType.cast(object));
}
}));
} else {
return observable;
}
}
}
先从mStickyEventMap中寻找是否包含该类型的事件,返回空则说明没有sticky事件要发送,如果不为空则说明有sticky时间需要发送,Subject和Sticky事件进行合并,从而保证事件再注册之后也能被订阅。
使用如下:
public class TestStickyActivity extends AppCompatActivity {
private CompositeDisposable mCompositeDisposable = new CompositeDisposable();
private RxBus mRxBus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\_test\_sticky);
mRxBus = RxBus.get();
initData();
registerEvents();
}
private void registerEvents() {
mCompositeDisposable.add(mRxBus.registerSticky(StickyEvent.class, AndroidSchedulers.mainThread(), new Consumer<StickyEvent>() {
@Override
public void accept(StickyEvent stickyEvent) throws Exception {
System.out.println("stickEvent");
}
}));
}
private void initData() {
mRxBus.postSticky(new StickyEvent());
}
@Override
protected void onDestroy() {
super.onDestroy();
mRxBus.removeStickyEvent(StickyEvent.class);
mCompositeDisposable.clear();
}
}
完整代码如下:
public class RxBus {
private Relay<Object> bus = null;
private static RxBus instance;
private final Map<Class<?>, Object> mStickyEventMap;
/\*\*
\* 禁用构造方法
*/
private RxBus() {
bus = PublishRelay.create().toSerialized();
mStickyEventMap = new ConcurrentHashMap<>();
}
public static RxBus get() {
return Holder.BUS;
}
public void post(Object event) {
bus.accept(event);
}
/\*\*
\* 发送sticky事件
\*
\* @param event
*/
public void postSticky(Object event) {
synchronized (mStickyEventMap) {
mStickyEventMap.put(event.getClass(), event);
}
bus.accept(event);
}
public <T> Observable<T> toObservable(Class<T> eventType) {
return bus.ofType(eventType);
}
/\*\*
\* 转换成Observable对象
\*
\* @param eventType
\* @param <T>
\* @return
*/
public <T> Observable<T> toObservableSticky(final Class<T> eventType) {
synchronized (mStickyEventMap) {
Observable<T> observable = bus.ofType(eventType);
final Object object = mStickyEventMap.get(eventType);
if (object != null) {
return observable.mergeWith(Observable.create(new ObservableOnSubscribe<T>() {
@Override
public void subscribe(ObservableEmitter<T> emitter) throws Exception {
emitter.onNext(eventType.cast(object));
}
}));
} else {
return observable;
}
}
}
public boolean hasObservers() {
return bus.hasObservers();
}
public <T> Disposable register(Class<T> eventType, Scheduler scheduler, Consumer<T> onNext) {
return toObservable(eventType).observeOn(scheduler).subscribe(onNext);
}
public <T> Disposable register(Class<T> eventType, Scheduler scheduler, Consumer<T> onNext, Consumer onError, Action onComplete
, Consumer onSubscribe) {
return toObservable(eventType).observeOn(scheduler).subscribe(onNext, onError, onComplete, onSubscribe);
}
public <T> Disposable register(Class<T> eventType, Scheduler scheduler, Consumer<T> onNext, Consumer onError, Action onComplete
) {
return toObservable(eventType).observeOn(scheduler).subscribe(onNext, onError, onComplete);
}
public <T> Disposable register(Class<T> eventType, Scheduler scheduler, Consumer<T> onNext, Consumer onError
) {
return toObservable(eventType).observeOn(scheduler).subscribe(onNext, onError);
}
public <T> Disposable register(Class<T> eventType, Consumer<T> onNext) {
return toObservable(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext);
}
public <T> Disposable register(Class<T> eventType, Consumer<T> onNext, Consumer onError, Action onComplete
, Consumer onSubscribe) {
return toObservable(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext, onError, onComplete, onSubscribe);
}
public <T> Disposable register(Class<T> eventType, Consumer<T> onNext, Consumer onError, Action onComplete
) {
return toObservable(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext, onError, onComplete);
}
public <T> Disposable register(Class<T> eventType, Consumer<T> onNext, Consumer onError
) {
return toObservable(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext, onError);
}
public <T> Disposable registerSticky(Class<T> eventType, Scheduler scheduler, Consumer<T> onNext) {
return toObservableSticky(eventType).observeOn(scheduler).subscribe(onNext);
}
public <T> Disposable registerSticky(Class<T> eventType, Consumer<T> onNext) {
return toObservableSticky(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext);
}
public <T> Disposable registerSticky(Class<T> eventType, Consumer<T> onNext, Consumer onError) {
return toObservableSticky(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext, onError);
}
/\*\*
\* 移除指定的eventType的sticky事件
\*
\* @param eventType
\* @param <T>
\* @return
*/
public <T> T removeStickyEvent(Class<T> eventType) {
synchronized (mStickyEventMap) {
return eventType.cast(mStickyEventMap.remove(eventType));
}
}
/\*\*
\* 移除所有的sticky事件
*/
public void removeAllStickyEvents() {
mStickyEventMap.clear();
}
public void unregister(Disposable disposable) {
if (disposable != null && !disposable.isDisposed()) {
disposable.dispose();
}
}
private static class Holder {
private static final RxBus BUS = new RxBus();
}
}