2011-09-06 19 views
15

mam działalność („ApplicationActivity”), które nazywamy zamiarem usługę („DownloadService”)Android: intentservice, jak przerwać lub pominąć zadanie w kolejce handleintent

W intentService pobieranie plików z internetu w tle, ale chcę, aby być w stanie przerwać konkretną pobrania .........

Więc powiedzmy, że mogę umieścić 5 plików w kolejce: plik 1,2,3,4,5

zamiarem usługa rozpocznie pobieranie numeru 1, a następnie drugiego itd. ... 1) Czy istnieje sposób, aby powiedzieć służbie intencji przerwać to, co robisz w tej chwili w wydarzenie obsługi metody (w tym przypadku pobieranie pliku 1) i rozpocząć pobieranie następnego?

2) Czy można usunąć element z kolejki, np. Podczas pobierania pliku 1, usunąć plik 4 z kolejki, aby po numerze 3 przejść bezpośrednio do 5?

Wkrótce muszę sposób komunikacji z kolejki do wykonywania tych 2 proste operacje, ale nie znaleźliśmy nic przydatnych w internecie :(

tnx

+0

Nawet teraz chcę to samo, czy twój problem został rozwiązany? –

Odpowiedz

12

tworzę własne kopiowanie klasa MyIntentService oryginalny taki, który jest dość krótki i modyfikować dla własnych celów ........ w szczególności dla usunięcia elementu, możesz użyć metod ServiceHandler w moim przypadku:
mServiceHandler.removeMessages (appId);
, które usuwa wszystkie oczekujące posty wiadomości z pewnym kodem "co", które znajdują się w kolejce komunikatów, oznacza to, że musisz oznaczyć każdą wiadomość dodawaną w kolejce, dodając identyfikator w polu "co" każdej wiadomości. .... na przykład

public void onStart(Intent intent, int startId) 
{ 
    super.onStart(intent, startId); 
    Message msg = mServiceHandler.obtainMessage(); 
    msg.arg1 = startId; 
    msg.obj = intent; 
    msg.what = intent.getIntExtra("appId", 0); \\parameters that come from the outside 
+0

Czy możesz opublikować pełny kod dla mojego zrozumienia. –

1

można wiązać z intentservice i utworzyć metodę do anulowania lub de queu pobrania.

Here to szybkie poradnik czego może potrzebować

+0

Szybko przeczytam ten przewodnik, ale nie mogę zrozumieć, jak to może być przydatne w moim przypadku ..... jest dla usług i nie zamierzonych usług ....... i dla innych celów .... ... moim problemem jest to, że intentowa klasa usług nie zapewnia żadnej metody wybierania z kolejką ... jedyne co mogę zrobić, to skopiować i wkleić klasę intentService i zmodyfikować ją ... – Sgotenks

+0

cześć. intentservice to podstawowa klasa usługi. Nadal można wykonać powiązanie z nim. Wiązanie służy do interakcji z usługą. Tak więc w bindie możesz mieć stopcurrent, a nawet metodę dequeu, która ustawia flagę lub piszczy plik, jeśli masz obiekt kolejki. – Pintac

19

Dzięki @ user280560, znalazłem rozwiązanie oparte na twój komentarz :)

wystarczy dać bardziej konkretny przykład, gdzie chciałem wyczyścić kolejkę w niektórych przypadkach.

Najpierw skopiowałem źródło IntentService.java z here do mojego projektu (nie trzeba zmieniać nazw, można zachować IntentService.java, wystarczy zaimportować swoje i nie androida). Następnie dodałem tenYdo mojego źródła IntentService.

Teraz z moich usług, który rozciąga IntentService, chciałem wyczyścić kolejkę, gdy pewna akcja (login) został przekazany do służby, więc zastąpić onStartMethod, tak:

@Override 
public void onStart(Intent intent, int startId) { 
    if(intent.getAction().equals(ACTION_LOGIN)) { 
     //Login clears messages in the queue 
     clearQueue(); 
    } 
    super.onStart(intent, startId); 
} 

działa jak urok :)

Mam nadzieję, że ktoś pomoże ...

+1

Dobra robota. Czy zatrzymuje również działanie systemu lub po prostu zatrzymuje działanie w kolejce? – vandzi

+0

Nie sądzę, że przestanie działać. Nie ma to jak testowanie. Być może modyfikując nieco oryginalne źródło IntentService, które można osiągnąć. –

+5

powinieneś jawnie przypisać pole 'what' w komunikacie zamiast zakładać, że jego wartość wynosi 0.' co 'nie jest używane w źródle, więc powinno być bezpieczne używanie go do własnych celów. –

4

rozszerzyć klasę IntentService i zadeklarować listę dla odwołanego pozycji na nim i kiedy chcesz, aby anulować coś dodać do tej listy. na koniec, zanim przejmiesz swoje intencje, upewnij się, że nie zostało ono anulowane!

public class MyDownloadService extends IntentService { 
    private static List<String> canceledUrl; 

    public static void cancelDownload(String url){ 
     canceledUrl.add(url); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     if (intent != null) { 
      final String url = intent.getStringExtra(EXTRA_URL); 

      if(!canceledUrl.contains(url)) //if download has not been canceled already 
       downloadFile(url); 
      else 
       canceledUrl.remove(url); 
     } 
    } 
} 

Wiem, że ten kod działa, ponieważ testowałem go wcześniej, ale nie jestem pewien, czy to właściwy sposób!

+0

Nie zatrzymuje to już uruchomionych usług. Poza tym jest to dobre i proste rozwiązanie. –

0

Jak powiedział przez @JeffreyBlattman powyżej, lepiej jest grać bezpiecznie przez przypisanie własnego „co” wartość do wiadomości jak ta

@Override 
    public void onStart(@Nullable Intent intent, int startId) { 
     Message msg = mServiceHandler.obtainMessage(); 
     msg.arg1 = startId; 
     msg.obj = intent; 
     msg.what = 0; 
     mServiceHandler.sendMessage(msg); 
    } 

i wyczyścić kolejkę jak mServiceHandler.removeMessages(0).

Nadzieję, że pomaga.