How to execure RoboSpice requests synchronously? Is it possible? I would like to use RoboSpice in IntentService.
Edit:
From time to time comes the need to execute something synchronously e.g. in service. In my recent project I have to queue some different types of requests and I wanted to use IntentService with RoboSpice. In my case when I'm executing different requests I need to wait for results from request1
then pass data from it to request2
and execute it.
I want to have some kind of batch request queue. Lets say we have two types of request: request1
and request2
. request2
needs data fetched by request1
:
request1
request1
and pass to request2
request2
I wanted to use IntentService (queue) but it dies after starting requests because of async.
In my opinion using listeners or CountDownLatch isn't the best way.
As proposed by Riccardo Ciovatti on the RoboSpice mailing list, a direct answer to your question is :
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();
But this isn't a good idiom to use unless it's being executed on a background thread. Asynchronous processing is an essential feature of RoboSpice; it keeps the UI thread free.
Using RoboSpice in IntentService. Solved the problem with help of CountDownLatch. Let's say we have 2 different SpiceManagers and some syncMethods to execute in sequence in the IntentService.
Globals:
private final SpiceManager aSpiceManager =
new SpiceManager(ASpiceService.class);
private final SpiceManager bSpiceManager =
new SpiceManager(BSpiceService.class);
private CountDownLatch handleIntentLatch;
onHandleIntent: Before we execute syncMethodA - we init our CountDownLatch with 1. After executing syncMethodA we await() for countDown() on our latch. When later some method will call countDown() on our latch at least once - method onHandleIntent will continue it's execution and finish which will trigger IntentService onDestroy() callback.
@Override
protected void onHandleIntent(Intent intent) {
handleIntentLatch = new CountDownLatch(1);
syncMethodA();
try {
handleIntentLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
syncMethodA(): Suppose we need to launch some sync methods in sequence (syncMethodA which callback executes syncMethodB etc).
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 etc are the same - in onRequestSuccess we start next syncMethodX. In on onRequestFailure we countDown() our latch (handleIntentLatch).
Very important!!! In last syncMethodX in sequence (after which completion we want onHandleIntent method to continue it's execution and finish which will result IntentService to stop) - we countDown() our latch in onRequestSuccess ALSO.
onDestroy: here we stop our 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();
}
}
All should be OK now: no leaked Context, SpiceManagers will be killed in onDestroy AND ONLY AFTER callbacks are resolved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With