Android RXJava-创建一个可暂停的可观察对象(例如,使用缓冲区和窗口)

Android RXJava-创建一个可暂停的可观察对象(例如,使用缓冲区和窗口),android,rx-java,observable,Android,Rx Java,Observable,我想创建具有以下功能的可观察对象: Observable o = ...; // Variant 1 o = o.lift(new RxValve(getPauser(), 1000, getPauser().getValue()) // Variant 2 // o = o.compose(RXPauser.applyPauser(getPauser())); o .subscribeOn(Schedulers.io()) .observeOn(AndroidScheduler

我想创建具有以下功能的可观察对象:

Observable o = ...;
// Variant 1
o = o.lift(new RxValve(getPauser(), 1000, getPauser().getValue())
// Variant 2
// o = o.compose(RXPauser.applyPauser(getPauser()));
o
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe();
  • 暂停时缓冲所有项目
  • 在项目未暂停时立即发出项目
  • 暂停/恢复触发器必须来自另一个可观察到的
  • 它必须保存以供不在主线程上运行的可观察对象使用,并且必须保存以从主线程更改暂停/恢复状态
我想使用
BehaviorSubject
作为触发器,并将此触发器绑定到活动的
onResume
onPause
事件。(附加代码示例)

问题

我已经设置了一些东西,但它没有按预期工作。我使用它的方式如下:

Observable o = ...;
// Variant 1
o = o.lift(new RxValve(getPauser(), 1000, getPauser().getValue())
// Variant 2
// o = o.compose(RXPauser.applyPauser(getPauser()));
o
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe();
目前的问题是,变型1应该可以正常工作,但有时,事件不会发出-阀门不会发出,直到阀门一切正常工作(可能是螺纹问题…)!解决方案2更简单,而且似乎有效,但我不确定它是否真的更好,我不这么认为。实际上我不确定,为什么解决方案1有时会失败,所以我不确定解决方案2是否解决了(目前我还不知道)问题

有人能告诉我问题出在哪里,或者简单的解决方案是否可靠?或者给我一个可靠的解决方案

代码

Rx值

RxPuser函数

public static Observable.Transformer applyPauser(可观测暂停器)
{
返回可观察->暂停器(可观察,暂停器);
}
专用静态可观察暂停器(可观察源,可观察暂停器)
{
//当发射暂停时,此可观察项缓冲所有发射的项目
可观察的sharedSource=source.publish().refCount();
可观察队列=共享源
.buffer(pauser.distinctUntilChanged().filter(isResumed->!isResumed),aBoolean->pauser.distinctUntilChanged().filter(isResumed->isResumed))
.flatMap(l->从(l)可观察)
.doOnNext(t->L.d(RXPauser.class,“Pauser排队:”+t));
//此可观察对象发射发射未暂停发射时发射的所有项目
Observable window=sharedSource.window(pauser.distinctUntilChanged().filter(isResumed->isResumed),aBoolean->pauser.distinctUntilChanged().filter(isResumed->!isResumed))
.switchMap(tObservable->tObservable)
.doOnNext(t->L.d(RXPauser.class,“暂停器未排队:”+t));
//结合两个观察值
返回队列。合并(窗口)
.doOnNext(t->L.d(RXPauser.class,“暂停交付:”+t));
}
活动

公共类BaseActivity扩展了AppCompativity{
private final BehaviorSubject pauser=BehaviorSubject.create(false);
public BaseActivity(Bundle savedInstanceState)
{
超级(args);
最终类clazz=this.getClass();
暂停者
.doOnUnsubscribe(()->{
L.d(clazz,“Pauser取消订阅!”);
})
.订阅(aBoolean->{
L.d(克拉兹,“暂停者-”+(阿博兰?)继续说:“暂停”);
});
}
公共出版物主题getPauser()
{
回程暂停器;
}
@凌驾
受保护的void onResume()
{
super.onResume();
pauser.onNext(true);
}
@凌驾
受保护的void onPause()
{
pauser.onNext(假);
super.onPause();
}
}

您实际上可以使用
.buffer()
操作符传递它observable,定义何时停止缓冲,从书本中获取样本:

Observable.interval(100, TimeUnit.MILLISECONDS).take(10)
    .buffer(Observable.interval(250, TimeUnit.MILLISECONDS))
    .subscribe(System.out::println);
从第5章“驯服序列”开始:


您可以使用
PublishSubject
作为
Observable
将it元素输入到自定义操作符中。每次需要开始缓冲时,通过
Observable.defer(()->createBufferingValve())
创建实例。我为记录事件做了类似的事情。
Subject收集一些事件,并在10秒内将它们推送到服务器。

其主要思想是,例如,您有class
Event

public class Event {

    public String jsonData;

    public String getJsonData() {
        return jsonData;
    }

    public Event setJsonData(String jsonData) {
        this.jsonData = jsonData;
        return this;
    }
}
您应该为以下事件创建队列:

private PublishSubject<Event> eventQueue = PublishSubject.create();
然后您应该订阅它,并保留订阅,直到您不需要它:

eventSubscription = eventObservable.subscribe()

主页这有助于

到目前为止,试图回答这个问题的人缺少一个问题中明确的关键要求:“暂停/恢复触发器必须来自另一个可观察到的对象”。他们不需要固定的时间表。
    eventObservable = eventQueue.asObservable()
            .buffer(10, TimeUnit.SECONDS)   //flush events every 10 seconds
            .toList()
            .doOnNext(new Action1<List<Event>>() {
                @Override
                public void call(List<Event> events) {
                    apiClient.pushEvents(events);     //push your event
                }
            })
            .onErrorResumeNext(new Func1<Throwable, Observable<List<Event>>>() {
                @Override
                public Observable<List<Event>> call(Throwable throwable) {
                    return null;    //make sure, that on error will be never called
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io());
eventSubscription = eventObservable.subscribe()