我正试图建立一个经理来监视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;
}
答案 0 :(得分:0)
您必须使您的服务也实现Merge
。
然后,您可以使用Observable
运算符,当所有服务就绪时,该运算符也会触发A(int)
。
答案 1 :(得分:0)
您需要执行两个步骤。
Observable<Boolean>
的列表(或可观察到的)它可能看起来像这样。
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
,否则应避免使用它们。