Korzystanie z RoboSpice w IntentService. Rozwiązał problem za pomocą CountDownLatch. Powiedzmy, że mamy 2 różne SpiceManagers i niektóre metody SyncMethod, aby wykonać sekwencję w IntentService.
Globals:
private final SpiceManager aSpiceManager =
new SpiceManager(ASpiceService.class);
private final SpiceManager bSpiceManager =
new SpiceManager(BSpiceService.class);
private CountDownLatch handleIntentLatch;
onHandleIntent: Przed wykonujemy syncMethodA - my init, nasz CountDownLatch z 1. Po wykonaniu syncMethodA oczekujemy() do odliczania() na naszej zatrzask. Kiedy później jakiś sposób wywoła countDown() na naszym zatrzasku co najmniej raz - metoda onHandleIntent będzie kontynuować jego wykonywanie i zakończenie, co spowoduje wywołanie zwrotne IntentService onDestroy().
@Override
protected void onHandleIntent(Intent intent) {
handleIntentLatch = new CountDownLatch(1);
syncMethodA();
try {
handleIntentLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
syncMethodA(): Załóżmy, że chcemy uruchomić kilka metod synchronizacji w sekwencji (syncMethodA który zwrotna wykonuje 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 są takie same - w onRequestSuccess rozpoczynamy następny syncMethodX. W dniu onRequestFailure możemy countDown() nasz zatrzask (handleIntentLatch).
Bardzo ważne !!! W ostatniej syncMethodX w kolejności (po której zakończenie chcemy metoda onHandleIntent kontynuować to wykonanie i wykończenie, które spowodują IntentService powstrzymać) - my odliczanie() nasz zatrzask w onRequestSuccessTAKŻE.
onDestroy: tutaj zatrzymujemy naszych 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();
}
}
Wszystko powinno być OK teraz: nie wyciekły Kontekst, SpiceManagers zostanie zabity w onDestroy i dopiero po wywołania zwrotne są rozwiązane.
Mam ten sam problem, nad nim zbyt :( – Eefret