如何同步执行RoboSpice请求?可能吗?我想在IntentService中使用RoboSpice。
编辑:
有时需要同步执行某些操作,例如在服务中。在我最近的项目中,我必须排队一些不同类型的请求,我想将IntentService与RoboSpice一起使用。就我而言,当我执行不同的请求时,我需要等待request1
的结果,然后将数据从它传递到request2
并执行它。
我想要某种批量请求队列。假设我们有两种类型的请求:request1
和request2
。 request2
需要request1
提取的数据:
request1
request1
提取的数据并传递给request2
request2
我想使用IntentService(队列)但由于异步而在启动请求后死亡。
在我看来,使用听众或CountDownLatch并不是最佳方式。
答案 0 :(得分:7)
根据Riccardo Ciovatti on the RoboSpice mailing list的建议,您问题的直接答案是:
final CountDownLatch latch = new CountDownLatch(1);
final YourRequest request = new YourRequest();
spiceManager.execute(request, new RequestListener<YourResponse>() {
@Override
public void onRequestFailure(SpiceException spiceException) {
latch.countDown();
}
@Override
public void onRequestSuccess(YourResponse response) {
latch.countDown();
}
});
latch.await();
但除非它在后台线程上执行,否则这不是一个好用的习惯用法。异步处理是RoboSpice的基本特征;它保持UI线程免费。
答案 1 :(得分:1)
在IntentService中使用RoboSpice。在CountDownLatch的帮助下解决了这个问题。假设我们有2个不同的SpiceManagers和一些syncMethods在IntentService中按顺序执行。
<强>全局强>:
private final SpiceManager aSpiceManager =
new SpiceManager(ASpiceService.class);
private final SpiceManager bSpiceManager =
new SpiceManager(BSpiceService.class);
private CountDownLatch handleIntentLatch;
onHandleIntent :在我们执行syncMethodA之前 - 我们用1启动我们的CountDownLatch。执行syncMethodA之后,我们在latch上使用count(相位)来计算countDown()。稍后某些方法会在我们的锁存器上至少调用一次countDown() - 方法onHandleIntent将继续执行并完成,这将触发IntentService onDestroy()回调。
@Override
protected void onHandleIntent(Intent intent) {
handleIntentLatch = new CountDownLatch(1);
syncMethodA();
try {
handleIntentLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
<强> syncMethodA()强>: 假设我们需要按顺序启动一些同步方法(syncMethodA,回调执行syncMethodB等)。
private void syncMethodA() {
SpiceRequest requestA = new SpiceRequest();
if (!aSpiceManager.isStarted()) {
LogUtils.LOGD(TAG, "starting aSpiceManager");
aSpiceManager.start(getApplicationContext());
}
aSpiceManager.execute(requestA , new RequestListener<ResponseA>() {
@Override
public void onRequestSuccess(final ResponseA responseA) {
// SOME LOGIC
syncMethodB();
// SOME LOGIC
@Override
public void onRequestFailure(SpiceException spiceException) {
handleIntentLatch.countDown();
// SOME LOGIC
}
});
}
syncMethodB,syncMethodC等是相同的 - 在 onRequestSuccess 中我们启动下一个syncMethodX。在 onRequestFailure 中,我们countDown()我们的latch(handleIntentLatch)。
非常重要!!! 在最后的syncMethodX顺序中(在完成之后我们希望onHandleIntent方法继续执行并完成将导致IntentService停止) - 我们在 onRequestSuccess 中的countDown()我们的锁存器
onDestroy :在这里我们停止SpinceManagers。
@Override
public void onDestroy() {
super.onDestroy();
LogUtils.LOGD(TAG, "onDestroy");
shutDownSpiceManagers();
}
<强> shutDownSpiceManagers 强>:
private void shutDownSpiceManagers() {
if (aSpiceManager.isStarted()) {
LogUtils.LOGD(TAG, "stopping aSpiceManager");
aSpiceManager.shouldStop();
}
if (bSpiceManager.isStarted()) {
LogUtils.LOGD(TAG, "stopping bSpiceManager");
bSpiceManager.shouldStop();
}
}
现在一切都应该没问题:没有泄露的上下文,SpiceManagers将在onDestroy中被杀死并且仅在后回调被解决。
答案 2 :(得分:0)
如果您不想完全同步执行,但只希望按顺序按顺序执行请求,您可以编写自己的简单类,只在请求A成功或失败时执行请求B.像那样:https://github.com/Deepscorn/Shared/blob/master/app/src/main/java/com/gamelift/shared/request/base/RequestSequenceExecutor.java。 所以,代码看起来像:
sequenceExecutor.setRequest(new FirstRequest());
sequenceExecutor.setOnSuccessListener(FirstRequest.class, new OnSuccessListener {
public void onSuccess() {
sequenceExecutor.setRequest(new SecondRequest());
}
};
sequenceExecutor.setOnFaulListener(FirstRequest.class, new OnFailListener {
public void onFail() {
sequenceExecutor.setRequest(new OnFirstFailRequest());
}
};
sequenceExecutor.setOnSuccessListener(SecondRequest.class, new OnSuccessListener {
public void onSuccess() {
notifyDone();
return;
}
};
sequenceExecutor.setDefaultOnFailListener(new OnFailListener {
public void onFail(Exception e) {
notifyDone();
log(e);
return;
}
};
sequenceExecutor.execute() //starts execution