RxJava-等待Observable <list <service >>中所有服务的Observable <boolean>

时间:2018-08-10 08:28:07

标签: java android rx-java reactive-programming rx-java2

我正试图建立一个经理来监视Obsevable<List>中的所有服务是否准备就绪。

代码的一般概念类似于以下内容:

public class ServiceStuff {

    public interface Service {
        String getName();

        Observable<Boolean> monitorReady();
    }

    private BehaviorSubject<List<Service>> services = BehaviorSubject.createDefault(Collections.emptyList());

    ServiceStuff(List<Service> list) {
        services.onNext(list);
    }

    public void addService(Service service) {
        List<Service> newList = services.getValue();
        newList.add(service);
        services.onNext(newList);
    }

    public void removeService(Service service) {
        List<Service> newList = services.getValue();
        newList.remove(service);
        if (newList.remove(service)) {
            services.onNext(newList);
        }
    }

    public Observable<List<Service>> monitorServices() {
        return services.observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<Boolean> monitorServicesReady() {
        return [If monitorReady() for all services return true, emit true, else false]
    }

}

如何在不阻塞UI线程的情况下实现monitorServicesReady()方法?在将任何服务添加到列表之前,应该有可能开始监视。


更新:

我现在尝试通过一些修改来实现建议的cyroxis解决方案。 blockingIterable()正在对应用进行ANR,因为它永远不知道monitorServices()流何时结束。

public Observable<Boolean> monitorServicesReady() {
    Iterable<Observable<Boolean>> sources = monitorServices().flatMapIterable(x -> x).map(Service::monitorReady).blockingIterable();
    return Observable.combineLatest(sources, this::all);
}

private boolean all(Object[] values) {
    boolean result = true;
    for (boolean val : (Boolean[]) values) {
        result &= val;
    }
    return result;
}

2 个答案:

答案 0 :(得分:0)

您必须使您的服务也实现Merge。 然后,您可以使用Observable运算符,当所有服务就绪时,该运算符也会触发A(int)

答案 1 :(得分:0)

您需要执行两个步骤。

  1. 从“服务”对象中获取所有Observable<Boolean>的列表(或可观察到的)
  2. 对您在第1步中获得的收藏进行最新的组合

它可能看起来像这样。

private boolean all(Boolean[] values) {
  boolean result = true;
  for(boolean val : values) {
    result &= val;
  }
  return result;
}


public Observable<Boolean> monitorServicesReady() {
  Observable<Observable<Boolean>> sources = monitorServices.flatMapIterable(x -> x)
   .map(servie -> servies.monitorReady());

  return Observable.combineLatest(sources, this::all); 
}

注意:据我所知,您应该摆脱BehaviorSubject,构造函数提供了固定的Services列表,只需将其保存为{{ 1}}。除非确实需要List,否则应避免使用它们。