我有一种方法可以ping通名为computerItemList
的列表中的所有计算机,并检查它是否在线。我想通过向API发送并行请求来做到这一点。下面的代码模拟了来自服务器的响应,并且正在运行,但是当所有请求完成解锁ping按钮时,我需要信息。怎么做?
通常,我要对列表中的所有项目执行异步命令,然后等待所有操作完成。
public void pingComputers() {
for (ComputerItem computerItem : _computerItemList) {
Observable.just(computerItem)
.subscribeOn(Schedulers.io())
.subscribe(item -> {
int sleepTime = randomizer.nextInt(1000) + 200;
int status = randomizer.nextInt(ComputerStatus.values().length - 1) + 1;
Log.d(TAG, Thread.currentThread().getName() + " >>pingSelected: " + item + " sleep: " + sleepTime);
Thread.sleep(sleepTime);
item.setStatus(ComputerStatus.values()[status]);
updateComputerList();
});
}
}
更新 我写了这样的东西。可以吗?
public void ping2() {
Observable.fromIterable(_computerItemList)
.flatMap(computerItem -> {
return Observable.just(computerItem)
.subscribeOn(Schedulers.io())
.map(item -> {
int sleepTime = randomizer.nextInt(1000) + 200;
Log.d(TAG, "ping2: Sleeping for " + sleepTime);
Thread.sleep(sleepTime);
int status = randomizer.nextInt(ComputerStatus.values().length - 1) + 1;
item.setStatus(ComputerStatus.values()[status]);
updateComputerList();
return item;
});
}).doOnComplete(() -> Log.d(TAG, "ping2: COMPLETE")).subscribe();
}
更新-它正在工作!但这可以吗?
public void executeCommand(CommandType command) {
isWorking.setValue(true);
Observable.fromIterable(_computerItemList)
.subscribeOn(Schedulers.io())
.flatMap(computerItem -> createPingObservable(computerItem))
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> isWorking.setValue(false))
.subscribe();
}
private Observable<ComputerItem> createPingObservable(ComputerItem computerItem) {
return Observable.just(computerItem)
.subscribeOn(Schedulers.io())
.map(item -> {
int sleepTime = randomizer.nextInt(1000) + 200;
int status = randomizer.nextInt(ComputerStatus.values().length - 1) + 1;
Log.d(TAG, Thread.currentThread().getName() + ">>> executeCommand: PING");
Thread.sleep(sleepTime);
item.setStatus(ComputerStatus.values()[status]);
updateComputerList();
return item;
});
}
答案 0 :(得分:0)
更新-它正在工作!但这还可以吗?
否,以这种方式调用updateComputerList();
是不可行的,您将不得不synchronized
调用它,因为您将从多个线程中调用它,每个线程都试图改变状态。
我会这样:
Observable.fromIterable(list)
.flatMap(computerItem -> createPingObservable(computerItem))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(computerItem -> updateComputerList(computerItem));
}
另外,不要使用Thread.sleep(sleepTime);
,只需使用
.delay(randomizer.nextInt(1000) + 200, TimeUnit.MILLISECONDS)