最近一直在学习retrofit+rxjava+mvp,突然发现自己懂得太少了。在这样下去。以后找工作那只能哭了。现在技术更新太快了。上年的时候retrofit还是不特别火吧。今年面试就突然感觉到了一丝丝寒意很多面试官都问道了你会不会使用retrofit。你自己封装过没有。因为的确以前没用过。也就失去很多机会吧。但是只有发现自己的不足才能进步吗。在最近使用rxjava的时候突然发现。查的很多资料都不能使用。仔细研究后发现。原来rxjava升级了变成了rxjava2.和以前的版本内容很多不兼容。下面就说一说rxjava2.o的rxbus吧。
首先我们需要添加引用:
compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxjava:2.1.0'在我从github(https://github.com/ReactiveX/RxAndroid)上查找的时候这个是最新的版本.使用前需要添加这两个引用。
添加完引用后我们就开始编写rxbus代码如下:
package com.example.administrator.newnet.Base; import com.example.administrator.newnet.model.FunctionBean; import java.util.HashMap; import java.util.List; import io.reactivex.Flowable; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.annotations.NonNull; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; import io.reactivex.subjects.Subject; /** * Created by Administrator on 2018/1/3. * 该类的作用就是为了替代eventBus *http://blog.youkuaiyun.com/zcphappy/article/details/75255918 */ public class RxBus { private final Subject<Object> mBus; private static volatile RxBus instance; // private final FlowableProcessor<Object> mBus;//背压测试 /** * 默认私有化构造函数 * 当前这个地方没有进行背压 * 背压:http://flyou.ren/2017/04/05/%E5%85%B3%E4%BA%8ERxJava%E8%83%8C%E5%8E%8B/?utm_source=tuicool&utm_medium=referral */ private RxBus() { mBus = PublishSubject.create().toSerialized(); } /**背压测试*/ /* private RxBus(){ mBus = PublishProcessor.create().toSerialized(); }*/ /** * 单例模式 */ public static RxBus getInstance() { if (instance == null) { synchronized (RxBus.class) { if (instance == null) { instance = new RxBus(); } } } return instance; } /** * 将数据添加到订阅 * 这个地方是再添加订阅的地方。最好创建一个新的类用于数据的传递 */ public void post(@NonNull Object obj) { if (mBus.hasObservers()) {//判断当前是否已经添加订阅 mBus.onNext(obj); } } /**这个是传递集合如果有需要的话你也可以进行更改*/ public void post(@NonNull List<Object> obj) { if (mBus.hasObservers()) {//判断当前是否已经添加订阅 mBus.onNext(obj); } } /** * 注册,传递tClass的时候最好创建一个封装的类。这对数据的传递作用 *新更改仅仅抛出生成类和解析 */ public <T> Disposable register(Class<T> tClass,Consumer<T> consumer) { return mBus.ofType(tClass) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(consumer); } /** * 确定接收消息的类型 * @param aClass * @param <T> * @return * 下面为背压使用方式 */ /* public <T> Flowable<T> toFlowable(Class<T> aClass) { return mBus.ofType(aClass); }*/ /** * 保存订阅后的disposable * @param o * @param disposable */ private HashMap<String, CompositeDisposable> mSubscriptionMap; public void addSubscription(Object o, Disposable disposable) { if (mSubscriptionMap == null) { mSubscriptionMap = new HashMap<>(); } String key = o.getClass().getName(); if (mSubscriptionMap.get(key) != null) { mSubscriptionMap.get(key).add(disposable); } else { //一次性容器,可以持有多个并提供 添加和移除。 CompositeDisposable disposables = new CompositeDisposable(); disposables.add(disposable); mSubscriptionMap.put(key, disposables); } } /** * 取消订阅 * @param o 这个是你添加到订阅的的对象 */ public void unSubscribe(Object o) { if (mSubscriptionMap == null) { return; } String key = o.getClass().getName(); if (!mSubscriptionMap.containsKey(key)){ return; } if (mSubscriptionMap.get(key) != null) { mSubscriptionMap.get(key).dispose(); } mSubscriptionMap.remove(key); } }在rxjava1.o的时候subject的创建并不是现在的mSubject = PublishSubject.create().toSerialized();是下面的格式:mSubject = new SerializedSubject<>(PublishSubject.create());
但是如果你使用的是rxjava2的话你就无法使用PublishSubject因为SerializedSubject所需要的subject是来之于org.xxx的包下,而你的publishSubject是
来之于io.xx包下。因此这个地方会出现问题,由于rxbus出现的目的查了很多资料大概都是说为了取代eventbus.由于eventbus使用的是注解形式。
对于使用者来说维护性能不是太好。然后rxbus使用的观察者模式进行设计的维护性已经使用性更加方便。rxjava1.0的时候出现了背压。我第一次见到
背压的时候是一脸蒙蔽百脸蒙蔽。我靠我落伍了。完了我刚进入程序员搬砖的行业又要离开了。其实背压也没有那么难理解。也就是想bufferstring一样
对长度限制一样。这个地方就限制的调取的次数而已。一篇好的背压博客推荐个小伙伴们:
http://flyou.ren/2017/04/05/%E5%85%B3%E4%BA%8ERxJava%E8%83%8C%E5%8E%8B/?utm_source=tuicool&utm_medium=referral
当进入到rxjava2.0的时候背压就给取消了。但是也带来了新的弊端。可以通过博客了解到。我上面的rxbus是无背压状态。包含了注册。取消注册。发送数据
等操作。你仅仅需要拷贝代码即可。
步骤一:在你需要的类中进行注册:
//进行rxbus注册 register();
/**注册获取到数据*/ private void register(){ Disposable register = RxBus.getInstance().register(BaseBean.class, new Consumer<BaseBean>() { @Override public void accept(@NonNull BaseBean baseBean) throws Exception { /**这个地方获取到数据。并执行相应的操作*/ } }); //TODO 这个地方必须添加注册 RxBus.getInstance().addSubscription(this,register); }我的注册是再oncreate里面进行的注册。如果你使用中同样应该先注册然后再进行数据发送监听。如果你了解观察者模式那么就知道为啥这么做了。如果你
不知道观察者模式。需要了解一下毕竟rxjava是根据观察者模式编写。同时面试中也有很多问及到观察者模式:
https://www.jianshu.com/p/1025f644f100 你可以多查找一些博客进行进行进一步了解
在注册的时候一定要将执行RxBus.getInstance.addSubscription(this,regitster)这句话。因为如果你忘记执行这句话。那么你在ondestroy中调用
取消注册将无法执行。也因此会导致内存泄露。(内存泄露。内存溢出要区分)。注册完成之后开始进行数据的传递
第二步:
@Override public void getNetDate(BaseBean baseBean) { Log.i("main...",baseBean.getMsg()+"new"); RxBus.getInstance().post(baseBean); }传递数据通知观察者有数据产生。getNetDate这个方法是我封装的框架里面获取网络数据的方法。BaseBean是我封装的bean的基类,如果你使用的时候
最好创建一个专门的类用于数据的rxbus数据的传递。当数据传递后就会在注册的方法中获取到你传递的数据。
有的朋友会问。我传递的数据是集合怎么办?我的思路是创建一个类。然后将你的集合放到这个类中进行数据的传递。可能你们有其他的想法。只要能
传递就行嘻嘻。数据传递完成当页面消失的时候。一定不要忘记将页面给关闭掉。有人要问了为啥不将addSubscription这个方法封装起来只写一次
这样写我万一忘了咋办呢?这个地方没办法由于是和你当前的页面关联。如果你有好的思路可以告诉我。
第三步:注销
/**这个地方必须将views层和presenter层断开防止在页面关闭后数据传递到views层造成异常*/ @Override public void destroyPresenter() { RxBus.getInstance().unSubscribe(this); // if(childPresenter != null && childPresenter.isAttach()){ // childPresenter.desAttach(); //} }我这个地方是再ondestroy中执行的。destroyPresenter这个方法是再ondestory中的自己封装的方法.这样就完成了rxbus的封装以及使用。
下面是eventbus的博客:多了解一点没错。
http://blog.youkuaiyun.com/harvic880925/article/details/40660137
https://github.com/greenrobot/EventBus
自己查看的rxjava1.o的rxbus
https://www.jianshu.com/p/58c8e57a03e3
http://blog.youkuaiyun.com/wuqilianga/article/details/73519447
rxjava2.0的rxubs
http://blog.youkuaiyun.com/zcphappy/article/details/75255918