1、前言

在MVP架构中,view层通常会像presenter层发送事件来告知view层需要更新。这就带来一个问题:view和presenter之前互相持有,没有解决耦合问题。如何设计一种方式来解决这个问题呢?

2、RxJava

其实仔细想想,view层和presenter层直接的事件完全可以用观察者模式来实现,那RxJava应该能解决这个问题。有关RxJava可以查看官网及这个博客

3、实现

3.1 建立全局单例的RxBus类,给出实现

public final class RxBus {

public static RxBus getInstance() {

return Holder.BUS;

}

private static class Holder {

private static final RxBus BUS = new RxBus();

}

private final Subject mBus;

private RxBus() {

mBus = PublishSubject.create().toSerialized();

mStickyEvents = new ConcurrentHashMap<>();

}

public void post(Object obj) {

mBus.onNext(obj);

}

public Observable toObservable(Class clazz) {

return mBus.ofType(clazz);

}

public Observable toObservable() {

return mBus.hide();

}

public boolean hasObservers() {

return mBus.hasObservers();

}

3.2 在view层发送事件

private void postDelayed(IControlEvent IControlEvent) {

mPresenter.runPostDelayed(new Runnable() {

@Override

public void run() {

RxBus.getInstance().post(mainControlEvent);

}

});

}

这里mainControlEvent是IControlEvent的某个具体实现类。

3.3 presenter层接收事件

private Disposable mSubscribe;

protected void onSubscription() {

super.onSubscription();

RxUtils.dispose(mSubscribe);

mSubscribe = RxBus.getInstance().toObservable(MainControlEvent.class)

.distinctUntilChanged()

.compose(applySchedulers())

.subscribe(new Consumer() {

@Override

public void accept(MainControlEvent controlEvent) {

//业务逻辑

}

});

重要过程说明: 1、RxBus.getInstance()toObservable()

RxBus.getInstance().toObservable(MainControlEvent.class)

RxBus里,toObservable()方法的定义

public Observable toObservable(Class clazz) {

return mBus.ofType(clazz);

}

根据RxJava的文档ofType的作用就是过滤出指定的类,这里是MainControlEvent这个类 2、.distinctUntilChanged() 根据API文档描述,这个方法的作用是滤除相同的对象: 3、.compose() compose()方法的作用是将被观察者转换成指定的元素,这里

.compose(applySchedulers())

的作用是实现了线程间切换,并指定了去注册的时机:

private ObservableTransformer mObservableTransformer;

protected final ObservableTransformer applySchedulers() {

if (mObservableTransformer == null) {

mObservableTransformer = new ObservableTransformer() {

@NonNull

@Override

public ObservableSource apply(@NonNull io.reactivex.Observable upstream) {

if (mBaselovView.getActivity() != null && mBaselovView.lifecycle != null) {

return upstream.takeUntil(getDisposeSubject())

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.compose(new SimpleLogTransformer())

.compose(mBaselovView.lifecycle.bindUntilEvent(ActivityEvent.DESTROY));

}

}

return upstream.takeUntil(getDisposeSubject())

.subscribeOn(Schedulers.io())

.compose(new SimpleLogTransformer())

.observeOn(AndroidSchedulers.mainThread());

}

};

}

return (ObservableTransformer) mObservableTransformer;

}

在RxJava里,ObservableTransformer接口的定义就是将输入流转换为指定的输出流,当然也可以指定从io线程转换到android主线程。 4、.subscribe() 在.subscribe()方法里实现view层的更新

.subscribe(new Consumer() {

@Override

public void accept(MainControlEvent controlEvent) {

if (controlEvent != null) {

//业务逻辑

}

}

});

4、总结

以上,基于RxJava的MVP架构下view层到presenter层的事件以及presenter层到view层之间的更新就实现了。采用这种方法,view层和presenter层之间的解耦比较好,只是在代码中存在大量view和presenter的时候代码可能会难于追踪。

5、彩蛋

在以前的博文中,曾经分享过《Rxjava+retrofit框架备忘》。里面有RxJava和retrofit实现的请求框架,网络请求接口通过回调传递给UI。在今天介绍的这个基于RxJava的事件总线也可以和retrofit结合,实现另外一种风格的网络请求框架。

public void sendControlComm(ControlEnum controlEnum, IControlEvent controlEvent) {

Observable> responseObservable = null;

responseObservable = ControlRepository.getInstance().operationEngine(

new OperationRequest(controlEnum == ControlEnum.ENGINE_START_OPEN

? ControlCons.STATUS.ON : ControlCons.STATUS.OFF));

……

responseObservable.subscribeOn(Schedulers.io())

.compose(new SimpleLogTransformer>())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new ControlObserver(controlEvent));

……

}

protected class ControlObserver extends SimpleObserver> {

private Event mControlEvent;

public ControlObserver(Event controlEvent) {

this.mControlEvent = controlEvent;

}

@Override

public void onNext(BaseResponse response) {

super.onNext(response);

……

RxBus.getInstance().post(response.getData());

}

@Override

public void onError(Throwable e) {

super.onError(e);

……

}

}

采用这种方法,同样也实现了RxJava+retrofit的网络请求框架。

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: 

发表评论

返回顶部暗黑模式