2012-06-28 10 views
13

Mam na myśli android design considerations: AsyncTask vs Service (IntentService?)IntentService zostanie zabity po tym, jak zatrzymać mój wniosek

Według dyskusji, AsyncTask nie pasuje, bo jest ciasno „związany” do aktywności

Tak , Uruchamiam Thread (zakładam, że AsyncTask i Thread należą do tej samej kategorii), mają uruchomioną pętlę nieskończoności i wykonały następujące testy.

  • I rzucić mój wniosek, utrzymując naciskając klawisz wstecz, aż ujrzałem ekran główny. Wątek nadal działa.
  • zabiję mój wniosek, przechodząc do Zarządzaj aplikacjami -> App -> stop force. Wątek został zatrzymany.

Tak, spodziewam się po tym, jak zmienić Thread do Service, mój Service zachowa przy życiu nawet po rzucić lub zabić moją aplikację.


Intent intent = new Intent(this, SyncWithCloudService.class); 
startService(intent); 

public class SyncWithCloudService extends IntentService { 
    public SyncWithCloudService() { 
     super("SyncWithCloudService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     int i = 0; 
     while (true) { 
      Log.i("CHEOK", "Service i is " + (i++)); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException ex) { 
       Log.i("CHEOK", "", ex); 
      } 
     } 
    } 
} 

// Doesn't matter whether I use "android:process" or not. 
    <service 
     android:name="com.xxx.xml.SyncWithCloudService" 
     android:process=".my_process" > 
    </service> 

Jednak moim odkryciem jest to, że

  • I zamknij Moja aplikacja, trzymając wciśnięty tylny klawisz programowy, dopóki nie zobaczyłem ekranu głównego. Usługa nadal działa.
  • zabiję mój wniosek, przechodząc do Zarządzaj aplikacjami -> App -> stop force. Usługa jest zatrzymana.

Wygląda na to, że zachowanie się Service i Thread jest takie samo. Dlaczego więc powinienem używać Service zamiast Thread? Czy jest coś, czego mi brakowało? Myślałam, że mój Service powinien nadal działać, nawet po tym, jak zabiję moją aplikację?

Odpowiedz

10

Nie. Usługa przestanie działać po zabiciu aplikacji. Po zabiciu aplikacji wszystkie jego elementy zostają zabite (czynności, usługi itp.).

Ogólnie zachowanie wątku i usługi są podobne.Jeśli jednak uruchomisz wątek z działania, a następnie zamkniesz działanie (np. Zamkniesz aplikację), w końcu Android zauważy, że Twój proces nie zawiera żadnych aktywnych komponentów (ponieważ Android nie rozpoznaje wątku jako aktywnego komponentu) i po prostu zabije twój proces, tym samym zabijając wątek.

Jeśli jednak masz uruchomioną Usługę, Android zauważy, że masz uruchomioną usługę i nie zabija tak łatwo. Jednak możliwe jest, że Android zabije Twój proces serwisowy, jeśli nie jest "używany".

+2

Ale moje badania jest to, że kiedy rzuciłem mój wniosek (naciskając kilkakrotnie klawisz funkcyjny, aż do ekranu głównego), wątek nadal działa. Czy to dlatego, że mam tyle szczęścia, że ​​system operacyjny nie zabija mojego wątku? –

+2

Tak, twój wątek będzie działał przez jakiś czas, dopóki Android nie zdecyduje się zabić procesu. Nie robi tego od razu, robi to tylko wtedy, gdy wydaje się, że tak jest. Nie masz kontroli nad tym, kiedy proces zostanie zabity. –

+0

OK. Dzięki. Testuję, aby uruchomić go przez kilka godzin i zobaczyć, jak to działa. W przypadku usługi Android "gwarantuje", że nie zabije go? Ponieważ mam pętlę nieskończoności w niej uruchomioną (do testowania). –

1

Używasz . Service będzie działać, dopóki kod się nie skończy lub dopóki Android nie zdecyduje, że powinien zostać zabity. Sprawdź na bound services. Na twoim Activity.onDestroy() powinieneś zadzwonić pod numer unbindService().

4

W rzeczywistości istnieją różne rodzaje usług, które można wdrożyć. Użyj Service zamiast IntentService. Tam musisz spojrzeć na START_STICKY, START_NOT_STICKY i START_REDELIVER_INTENT możesz utrzymać swoją usługę działającą w tle, nawet jeśli twoja działalność umiera. Android services

1

W swojej IntentService można zastąpić onStartCommand() powrót START_REDELIVER_INTENT

A jeśli zabity, usługa zostanie ponownie uruchomiony automatycznie przez system po pewnym czasie z tego samego intencyjny.

Koniecznie zadzwoń super wykonanie na onStartCommand() tak:

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    super.onStartCommand(intent,flags,startId); 
    return START_REDELIVER_INTENT; 
} 
Powiązane problemy