compose,takeUntil ,Share

因为用到Rxlifecycle ,然后就顺手看了下 源码,最主要的就是

compose,takeUntil ,Share(Publish, Refcount) 这个几个操作符了。
看的同时在网上 也搜了下 相关方面的资料,部分也借鉴了下
http://www.cnblogs.com/liulipeng/p/5050827.html
http://ju.outofmemory.cn/entry/255976

源码主要代码

 public final <T> Transformer<T, T> bindUntilEvent(ActivityEvent event) {
        return RxLifecycle.bindUntilActivityEvent(this.lifecycleSubject, event);
    }

    public final <T> Transformer<T, T> bindToLifecycle() {
        return RxLifecycle.bindActivity(this.lifecycleSubject);
    }
 private static <T, R> Transformer<T, T> bindUntilEvent(final Observable<R> lifecycle, final R event) {
        if(lifecycle == null) {
            throw new IllegalArgumentException("Lifecycle must be given");
        } else if(event == null) {
            throw new IllegalArgumentException("Event must be given");
        } else {
            return new Transformer() {
                public Observable<T> call(Observable<T> source) {
                    return source.takeUntil(lifecycle.takeFirst(new Func1() {
                        public Boolean call(R lifecycleEvent) {
                            return Boolean.valueOf(lifecycleEvent == event);
                        }
                    }));
                }
            };
        }
    }


   private static <T, R> Transformer<T, T> bind(Observable<R> lifecycle, final Func1<R, R> correspondingEvents) {
        if(lifecycle == null) {
            throw new IllegalArgumentException("Lifecycle must be given");
        } else {
            final Observable sharedLifecycle = lifecycle.share();
            return new Transformer() {
                public Observable<T> call(Observable<T> source) {
                    return source.takeUntil(Observable.combineLatest(sharedLifecycle.take(1).map(correspondingEvents), sharedLifecycle.skip(1), new Func2() {
                        public Boolean call(R bindUntilEvent, R lifecycleEvent) {
                            return Boolean.valueOf(lifecycleEvent == bindUntilEvent);
                        }
                    }).onErrorReturn(RxLifecycle.RESUME_FUNCTION).takeFirst(RxLifecycle.SHOULD_COMPLETE));
                }
            };
        }
    }

1.compose
Compose操作符是将源Observable按照自定义的方式转化成另外一个新的Observable。

public <R> Observable<R> compose(Observable.Transformer<? super T,? extends R> transformer)

Compose 和 Transformer 是结合使用的
也参考了些别人总结出来的东西,感觉这样更快,更容易理解学习

 <T> Transformer<T, T> test() {
 return new Transformer<T, T>() {

   // 这里的 observable 是重点, 是原observable
   @Override
   public Observable<T> call(Observable<T> observable) {
     return xxxx;
   }
 };
}

引用

.compose(<String>test())

传参的例子
http://ju.outofmemory.cn/entry/255976

private static class AverageAcc {
        public final int sum;
        public final int count;
        public AverageAcc(int sum, int count) {
            this.sum = sum;
            this.count = count;
        }
    }

    final int threshold;

    public RunningAverage() {
        this.threshold = Integer.MAX_VALUE;
    }

    public RunningAverage(int threshold) {
        this.threshold = threshold;
    }

    @Override
    public Observable<Double> call(Observable<Integer> source) {
        return source
            .filter(i -> i< this.threshold)
            .scan(
                new AverageAcc(0,0),
                (acc, v) -> new AverageAcc(acc.sum + v, acc.count + 1))
            .filter(acc -> acc.count > 0)
            .map(acc -> acc.sum/(double)acc.count);
    }
}

调用

source.compose(new RunningAverage(5))

2.takeUntil
这个 之前 只注意过 takeFirst这些类似的,这个还真没怎么注意
TakeUntil — 发射来自原始Observable的数据,直到第二个Observable发射了一个数据或一个通知

如果lifecycle.takeFirst发射了一条数据,takeUntil就回触发,source Observable就回停止发射数据,执行Unsubscribe,流自动结束。
源码,这里(这里代码的意思就是,他去判断现在当前activity的状态,如果和你传入的比较相同的话,就会返回true了,然后就Unsubscribe,自然后面的订阅者就收不到消息了)

return new Observable.Transformer<T, T>() {
    @Override
    public Observable<T> call(Observable<T> source) {
        return source.takeUntil(
            lifecycle.takeFirst(new Func1<R, Boolean>() {
                @Override
                public Boolean call(R lifecycleEvent) {
                    return lifecycleEvent == event;
                }
            })
        );
    }
};

combineLatest 操作符

第一个参数:取BehaviorSubject发射的数据中的第一个,然后转换成对应的生命周期。例如在onStart()中调用了bindToLifecycle,take(1)后的数据是ActivityEvent.START,经过map(),返回ActivityEvent.STOP。

第二个参数:从BehaviorSubject发射的数据中经过.skip(1)操作符,过滤掉第一个数据。例如在onStart()中调用了bindToLifecycle,在后续的生命周期中会收到,ActivityEvent.RESUME、ActivityEvent.PAUSE、ActivityEvent.STOP、ActivityEvent.DESTROY

第三个参数:作用是combineFunction,把前两个参数最近发射的数据按照规则进行合并。规则是比对两次事件是否相等,然后合并后数据返回Boolean结果。比如params2发射ActivityEvent.RESUME的时候,和params1发射的ActivityEvent.STOP进行比对,返回false结果;params2发射ActivityEvent.STOP的时候,和params1发射的ActivityEvent.STOP进行比对,返回true结果。

3. share
转载 http://www.cnblogs.com/liulipeng/p/5050353.html
看源码知道.share()操作符是.publish().refcount()调用链的包装。
先来看ConnectedObservable

“ConnectedObservable” – This is a kind of observable which doesn’t emit items even if subscribed to.
It only starts emitting items after its .connect() method is called.
因为这个原因,在ConnectedObservable的connect这个方法被调用之前,connected obesrvable也被认为是“冷”和不活跃。

再看publish方法

.publish()– This method allows us to change an ordinary observable into a “ConnectedObservable”.
Simply call this method on an ordinary observable and it becomes a connected one.
现在我们知道了share操作符的1/2,那么为什么需要运用Connected Observable这个操作符呢?文档上是这么写的:

In this way you can wait for all intended Subscribers to subscribe to the Observable before the Observable begins emitting items.
这就意味着publish可以调用多个subscriber。当你有超过一个订阅者的时候,处理每个订阅和正确的销毁他们变得棘手。 为了使这个更方便,Rx发明了这个魔法操作符refcount():

refcount() – This operator keeps track of how many subscribers are subscribed to the resulting Observable and
refrains from disconnecting from the source ConnectedObservable until all such Observables are unsubscribed.
refcount本质上在后台维护着一个引用计数器,当一个subscription需要取消订阅或者销毁的时候,发出一个正确的动作。

我们再次看一下debouncedBuffer的例子,看一下在哪,share是怎么用的。

Observable<Object> tapEventEmitter=_rxBus.toObserverable().share();
// which is really the same as:
Observable<Object> tapEventEmitter=_rxBus.toObserverable().publish().refcount();

我们现在有了一个”shareable”的名字叫”tapEventEmitter”的observable。 因为他是可以分享的,而且还不是“live”(share操作符中的publish调用使其变成一个ConnectedObservable), 我们可以用他构成我们的Observables,而且要确保我们有了一个原始的observable的引用 (这个例子中原始的observable是_rxBus.toObserverable()).

Observable<Object> tapEventEmitter = _rxBus.toObserverable().share();
Observable<Object> debouncedEventEmitter = tapEventEmitter.debounce(1, TimeUnit.SECONDS);
tapEventEmitter.buffer(debouncedEventEmitter)
//...

所有的这一切看起来都很好。然而这个实现会有一个可能的竞争条件。因为这有两个subscribers(debounce and buffer)而且会在不同的时间点发生,所以竞争条件就会发生。 记住RxBus是由hot/live Subject支持的不断的发射数据。通过使用share操作符,我们保证引用的是同一个资源。 而不是subscribers在不同的时间点订阅,他们会收到准确的相同的数据。

The race condition is when the two consumers subscribe. Often on a hot stream it doesn’t matter when subscribers come and go,and refCount is perfect for that.
The race condition refCount protects against is having only 1 active subscription upstream. However,if 2 Subscribers subscribe to a refcounted stream that emits 1, 2, 3, 4, 5, the first may get 1, 2, 3, 4, 5 and the second may get 2, 3, 4, 5.

To ensure all subscribers start at exactly the same time and get the exact same values, refCount can not be used.
Either ConnectableObservable with a manual, imperative invocation of connect needs to be done, or the variant of publish(function)which connects everything within the function before connecting the upstream.
在我们的用法中几乎立即执行所以没有什么关系。但是我们原始的意图是把debouncedBuffer方法作为一个单独的操作符。 如果相同的事件没有被发射出去,从概念上看起来是不正确的。

通过Bean后来的建议,我添加了一个更好的第三方的实现,用来处理这种竞争条件。

// don't start emitting items just yet by turning the observable to a connected one
ConnectableObservable<Object> tapEventEmitter = _rxBus.toObserverable().publish();

tapEventEmitter.publish((Func1) (stream) -> {

// inside `publish`, "stream" is truly multicasted

// applying the same technique for getting a debounced buffer sequence
    return stream.buffer(stream.debounce(1, TimeUnit.SECONDS));

}).subscribe((Action1) (taps) {
_showTapCount(taps.size());
});

// start listening to events now
tapEventEmitter.connect();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值