How to execute RoboSpice requests synchronously?

How to execute RoboSpice requests synchronously? Is it possible? I would like to use RoboSpice in an IntentService.

Edit:

From time to time there is a need to do something synchronously, for example. in service. In my recent project, I have to queue several different types of requests, and I wanted to use IntentService with RoboSpice. In my case, when I execute different requests, I need to wait for the results from request1 , and then transfer the data from it to request2 and execute it.

I want to have some kind of batch request queue. Suppose we have two types of requests: request1 and request2 . request2 needs the data received with request1 :

  • execute request1
  • Wait
  • get the data received with request1 and go to request2
  • fulfill request2
  • Wait
  • go over 1.

I wanted to use IntentService (queue), but it dies after running requests due to async.

In my opinion, using listeners or CountDownLatch is not the best way.

+7
robospice
source share
3 answers

As suggested by Riccardo Ciovatti on the RoboSpice mailing list , a direct answer to your question:

 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 is not a good idiom to use if it is not running in the background thread. Asynchronous processing is an important feature of RoboSpice; It does not support user interface thread.

+7
source share

Using RoboSpice in IntentService. Solved the problem using CountDownLatch. Say we have 2 different SpiceManagers and some syncMethods to execute sequentially in an IntentService.

Globals

 private final SpiceManager aSpiceManager = new SpiceManager(ASpiceService.class); private final SpiceManager bSpiceManager = new SpiceManager(BSpiceService.class); private CountDownLatch handleIntentLatch; 

onHandleIntent : before executing syncMethodA - we start our CountDownLatch from 1. After executing syncMethodA, we expect () for countDown () on our latch. When later any method calls countDown () on our latch at least once - the onHandleIntent method will continue to execute and complete the execution, which will call the 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 run some synchronization methods in a sequence (syncMethodA, which calls the syncMethodB callback, 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. same - in onRequestSuccess we run the following syncMethodX. In onRequestFailure we count () our latch (handleIntentLatch).

Very important!!! In the last syncMethodX in the sequence (after which we want the onHandleIntent method to continue execution and complete, which will cause the IntentService to stop) - we count () our latch in onRequestSuccess ALSO .

onDestroy : here we stop our Spince managers.

 @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(); } } 

Now everything should be in order: there is no leak Context, SpiceManagers will be killed in onDestroy AND ONLY AFTER callbacks are allowed.

+1
source share

If you don’t want to execute synchronously exactly, but want the requests to be executed sequentially in some order, you can write your own simple class that will simply execute request B when request A is successful or unsuccessful. For example: https://github.com/Deepscorn/Shared/blob/master/app/src/main/java/com/gamelift/shared/request/base/RequestSequenceExecutor.java . So, the code will look like this:

 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 
0
source share

All Articles