RxPresenter浅析

来源:互联网 发布:itunes安装软件 编辑:程序博客网 时间:2024/06/01 15:27

(注:由于手机号验证问题,n6323438的博文转移至此)
今天要介绍的是github上一个Android开源框架: android-starter-kit (Rx部分)

链接: https://github.com/qijitech/android-starter-kit

先看变量:

private final BehaviorSubject<View> views = BehaviorSubject.create();private final HashMap<Integer, Func0<Subscription>> restartables = new HashMap<>(); //请求private final HashMap<Integer, Subscription> restartableSubscriptions = new HashMap<>(); ////请求subscribe后的subscriptionprivate final ArrayList<Integer> requested = new ArrayList<>(); ////已经开始的请求对应的id

看第一个方法restartable

 public void restartable(int restartableId, Func0<Subscription> factory) {        restartables.put(restartableId, factory);        if (requested.contains(restartableId))            start(restartableId);    }

参数有Id和一个返回Subscription的Func0接口.
先put进去restartables这个HashMap中, 然后检查requested这个ArrayList中有没有传进来的restartableId, 如果有, 就会取消这个请求并重新开始.

stop方法

源码比较简单, 我就不贴了
从requested中去除传入的restartableId, 然后在restartableSubscriptions找到对应的subscription, 并调用unsubscribe.

start方法

首先调用stop方法, 然后把restartableId放进requested中, 然后取出对应的Func0接口并调用, 得到的subscription放进restartableSubscriptions中.

一般并不会直接用restartable方法, 因为这里提供了3个经过封装的方法:

1: restartableFirst方法

public <T> void restartableFirst(int restartableId, final Func0<Observable<T>> observableFactory,        final Action2<View, T> onNext, @Nullable final Action2<View, Throwable> onError) {        restartable(restartableId, new Func0<Subscription>() {            @Override            public Subscription call() {                return observableFactory.call()                    .compose(RxPresenter.this.<T>deliverFirst())                    .subscribe(split(onNext, onError));            }        });    }

这个方法可以对observable进行处理, 从源码可以看出, 调用了observableFactory的call方法, 经过compose再subscribe.
那么这个compose做了什么呢? 变换就在DeliverFirst这个类中.
先看构造方法:

public DeliverFirst(Observable<View> view) {        this.view = view;    }

传入了observable, 这个observable其实就是RxPresenter中的一个变量 BehaviorSubject<View> views = BehaviorSubject.create();
BehaviourSubject简单来说就是, 当有Observer订阅的时候, 在这个订阅之前的一个事件也会发射出去. 具体自行搜索
关键就在call方法 :

public Observable<Delivery<View, T>> call(Observable<T> observable) {        return observable.materialize()            .take(1)            .switchMap(new Func1<Notification<T>, Observable<? extends Delivery<View, T>>>() {                @Override                public Observable<? extends Delivery<View, T>> call(final Notification<T> notification) {                    return view.map(new Func1<View, Delivery<View, T>>() {                        @Override                        public Delivery<View, T> call(View view) {                            return view == null ? null : new Delivery<>(view, notification);                        }                    });                }            })            .filter(new Func1<Delivery<View, T>, Boolean>() {                @Override                public Boolean call(Delivery<View, T> delivery) {                    return delivery != null;                }            })            .take(1);    }

首先进行materialize变换(这个就不解释了), 之后只取第一个notification, 然后要把notificatiion变成Observable, 这里有点绕.
看里面的call方法, 那个BehaviourSubject原来是发射View泛型的, 现在通过map转变为发射Delivery
如果原来发射的View泛型为null, 那这个Delivery就为null. (这里不太好解释, 仔细看看源码应该能明白)
最后来个filter再取第一个, 完成了.
小结: 这个变换的作用其实是, 如果View泛型已经脱离了Presenter, 那结果就不会传递到处理的方法中.
在之前介绍NucleusSupportFragment时已经提到, 当fragment进入onPause, presenter就会放弃对fragment的引用.

现在回到restartableFirst方法, subscribe的参数是一个Action1接口, 这个Action1就是调用了delivery的split方法, 参数为restartableFirst的参数onNext和onError.
这个delivery是含有一个notification的, 那split方法就是根据notification是onNext还是onError, 执行相应的方法.

2: restartableReplay方法

其实和restartableFirst很类似, 不同在于它用的是DeliverReplay
DeliverReplay的call方法:

public Observable<Delivery<View, T>> call(Observable<T> observable) {        final ReplaySubject<Notification<T>> subject = ReplaySubject.create();        final Subscription subscription = observable            .materialize()            .filter(new Func1<Notification<T>, Boolean>() {                @Override                public Boolean call(Notification<T> notification) {                    return !notification.isOnCompleted();                }            })            .subscribe(subject);        return view            .switchMap(new Func1<View, Observable<Delivery<View, T>>>() {                @Override                public Observable<Delivery<View, T>> call(final View view) {                    return view == null ? Observable.<Delivery<View, T>>never() : subject                        .map(new Func1<Notification<T>, Delivery<View, T>>() {                            @Override                            public Delivery<View, T> call(Notification<T> notification) {                                return new Delivery<>(view, notification);                            }                        });                }            })            .doOnUnsubscribe(new Action0() {                @Override                public void call() {                    subscription.unsubscribe();                }            });    }

首先也是materialize变换, 然后onComplete事件不会被传递, 订阅的是一个ReplaySubject.
ReplaySubject就是, 当有Observer订阅的时候, 会发射所有的事件.
这里其实就是把除了onComplete的所有事件存到ReplaySubject中.
返回的是对view进行map变换, 和上面讲的类似.

3: restartableLatestCache方法

不同的地方在于它用了DeliverLatestCache

public Observable<Delivery<View, T>> call(Observable<T> observable) {        return Observable            .combineLatest(                view,                observable                    .materialize()                    .filter(new Func1<Notification<T>, Boolean>() {                        @Override                        public Boolean call(Notification<T> notification) {                            return !notification.isOnCompleted();                        }                    }),                new Func2<View, Notification<T>, Delivery<View, T>>() {                    @Override                    public Delivery<View, T> call(View view, Notification<T> notification) {                        return view == null ? null : new Delivery<>(view, notification);                    }                })            .filter(new Func1<Delivery<View, T>, Boolean>() {                @Override                public Boolean call(Delivery<View, T> delivery) {                    return delivery != null;                }            });    }}

首先调用Observable.combineLatest, 简单解释一下, 这个方法可以把两个Observable发射的事件, 通过自定的方法合并成一个新事件.
第一个Observable就是view, 第二个是对传入的observable进行materialize变换,再过滤掉onComplete事件;
自定方法是, 如果发射的泛型View不为null,则返回Delivery; 为null, 就返回null
最后也是过滤.

这3个方法各有不同,
restartableFirst方法只会取发射的第一个事件;
restartableReplay会先把所有事件存起来,再一起发射;
restartableLatestCache每发射一个事件, 都会对应到当时的view状态

最后看一下 onTakeView和onDropView

    protected void onTakeView(View view) {        views.onNext(view);    }      protected void onDropView() {        views.onNext(null);    }    

现在知道为什么可以获取到实时View的状态了吧

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两岁宝宝说话晚怎么办 6岁儿童说话结巴怎么办 2岁宝宝呕吐拉稀怎么办 2岁宝宝突然呕吐怎么办 2岁宝宝呕吐发烧怎么办 2岁宝宝呕吐厉害怎么办 1岁宝宝半夜呕吐怎么办 2岁半宝宝呕吐怎么办 2岁宝宝半夜呕吐怎么办 两岁宝宝一直吐怎么办 原画师老了以后怎么办 孩子不想上学怎么办怎么去说服 嫉妒别人比我好怎么办 三岁宝宝爱打人怎么办 1岁宝宝喜欢打人怎么办 ps图层解锁不了怎么办 沈腾结婚马丽怎么办 延长甲没有纸托怎么办 高考第一志愿没录取怎么办 电子画颜料干了怎么办 数字画颜料干了怎么办 彩砂纸画不好了怎么办 宝宝吃了油画棒怎么办 2岁宝宝不爱刷牙怎么办 两岁宝宝不刷牙怎么办 1岁宝宝不爱刷牙怎么办 3岁宝宝不肯刷牙怎么办 20岁没学历迷茫怎么办 四岁了不长头发怎么办 17岁掉头发严重怎么办 头发很油,又少怎么办 25岁头发变稀怎么办 宝宝头发少又黄怎么办 头旋附近头发少怎么办 25岁掉头发严重怎么办 2岁宝宝头发稀少怎么办 掉头发很厉害怎么办吧 头发点的很厉害怎么办 为什么掉头发很厉害怎么办 产后2年脱发严重怎么办 产妇掉头发很厉害怎么办