5

Mam usługę, która ma zmienny czas życia. Może wykonać od 5 minut do 2 godzin (na przykład). Więc szukam najlepszego podejścia do tego, a moja usługa musi osiągnąć następujące funkcje:Najlepsze podejście do wykonywania usług w systemie Android

  • Wysyłanie (do mojego serwera) łac długie co 5 sekund i dodatkowe informacje (string „s, boolean 's i int' s)

próbowałem "normalne" usługi i starał się zrobić coś takiego, aby to osiągnąć:

public class MyFiveSecondsService extends Service { 
    private Handler handler; 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      //here send my new data 
     } 
    }; 

    public void onCreate(){ 
     super.onCreate(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if(handler == null){ 
      handler = new Handler(); 
     } 

     handler.post(r); 

     return super.onStartCommand(intent, flags, startId); 
    } 
} 

Właściwie że kod działa, ale mam pewne pr wydajności oblems z tym podejściem, więc starałem się zrobić coś takiego:

public class SendUniquePositionIntentService extends IntentService { 

    public SendUniquePositionIntentService() { 
     super("co.bomboapp.Service.IntentService.SendUniquePositionIntentService"); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     //do the logic here 
    } 
} 

public class MyFiveSecondsService extends Service { 
    private Handler handler; 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      //call my SendUniquePositionIntentService here 
     } 
    }; 

    public void onCreate(){ 
     super.onCreate(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if(handler == null){ 
      handler = new Handler(); 
     } 

     handler.post(r); 

     return super.onStartCommand(intent, flags, startId); 
    } 
} 

I to podejście nie działało, kiedy zamknęły aplikację każda usługa biegł. Tak więc przed rozpoczęciem jakiejkolwiek innej próby osiągnięcia tego, potrzebuję jakiegoś kierunku, jakie jest najlepsze podejście do wykonania "nieskończonej pętli" i utrzymania wydajności?

Używam Android 4.1 jako min. API, a kierowanie na 5.0 API. Moje urządzenie testowe to Nexus 5 działające Android 6. W tej chwili używam bazy danych jako bazy danych parse.com.

+0

Usługi są zaprojektowane tak, aby nadal działały po zniszczeniu Twojej działalności. Więc nie zapomnij przerwać usługi, gdy praca zostanie zakończona. –

+0

Zatrzymuje ją w odpowiednim momencie, ale dzięki, i tak! – guisantogui

+0

dlaczego nie nazywasz bezpośrednio SendUniquePositionIntentService? Myślę, że wystarczy spełnić twoje wymagania używając SendUniquePositionIntentService. – xxxzhi

Odpowiedz

3

„Próbowałem«normalne»usługi ... ale mam pewne problemy z wydajnością”

Domyślnie usługa działa na głównym wątku aplikacji, więc podczas tworzenia obsługi z

public int onStartCommand(Intent intent, int flags, int startId) { 
    if(handler == null){ 
     handler = new Handler(); 
    } 
    ... 
} 

Program obsługi jest powiązany z głównym wątkiem: Looper, a wszystkie komunikaty i pliki run są dostarczane, a następnie wykonywane na wątku. To jest powód "problemów z wydajnością" ". Od documentation:

Pamiętaj, że jeśli nie skorzystać z usługi, to nadal działa w głównym wątku danej aplikacji domyślnie ...

odniesieniu do drugiego podejścia i części

"... gdy zamknąłem aplikację, usługa nadal działała"

Nie wspomniano, jak dokładnie "zamkniesz" aplikację, ale widzę tylko:

public int onStartCommand(Intent intent, int flags, int startId) { 
    ... 
    return super.onStartCommand(intent, flags, startId); 
} 

co oznacza, że ​​jeśli system zabije usługę, domyślnie zostanie odtworzony.Więc jeśli „zamykania” aplikacja oznacza, zabijając go, następujący łańcuch działań następuje:

  1. System odtwarza MyFiveSecondsService,
  2. onStartCommand() nazywa i Handler Wysyła runnable
  3. w metodzie SendUniquePositionIntentServicerun() rozpoczyna

z dokumentacji onStartCommand():

domyślne wywołania implementacji onStart (Intent, int) i zwraca wartość START_STICKY lub START_STICKY_COMPATIBILITY.

Należy zauważyć, że począwszy od służby innym (jak zaczynając SendUniquePositionIntentService z MyFiveSecondsService w danym przypadku) jest zbędne, jeśli nie ma na celu.

Ostatnia część twojego pytania jest dla mnie myląca. Z jednej strony to nie działa dla ciebie, ponieważ "... jakakolwiek usługa ciągle działa", ale z drugiej strony, chciałbyś "zrobić to" nieskończoną usługę pętli "" ...?

Jeśli trzeba tylko wysłać taką informację, „smyczki, logicznych i wskazówki” na serwerze (bez sprzężenia zwrotnego do komponentu, który uruchomił usługę), przypuszczam, że wystarczy po prostu do użycia IntentService. Jest to framework "out-of-box", który działa na wątku w tle (pozwalając uniknąć zamrożenia głównego wątku) i zatrzymuje się po zakończeniu. Jako przykład możesz użyć dokumentacji na IntentService - jest dobrze napisana.

Należy również pamiętać, że zachowanie usługi po jej zabiciu przez system zależy od flagi zwróconej przez onStartCommand(). Na przykład. użyj START_NOT_STICKY, aby nie odtwarzać usługi po zabiciu aplikacji lub START_REDELIVER_INTENT, aby odtworzyć ją ponownie z ostatnim Intent ponownie dostarczonym.

+0

moim zamiarem przy użyciu zarówno usługi, jak i serveral intentServices było świadczenie usługi "nieskończonej pętli", nawet jeśli użytkownik zamknął aplikację, podczas gdy intentService ma dedykowany wątek do ciężkiej pracy. – guisantogui

+1

@guisantogui Dlaczego _ "using serveral intentServices" _? Czy nie wystarczy uruchomić tylko jedną 'IntentService' i uruchomić w niej wiele wątków. (Zajrzyj do [ThreadPoolExecutor] (http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html), aby zarządzać wątkami). Wewnątrz 'intentService'' onHandleIntent() 'możesz zrobić swoją pracę jako" nieskończony ", jak chcesz. Ważne jest, aby upewnić się, że usługa jest żywa po zamknięciu aplikacji, którą można zarządzać odpowiednimi flagami zgodnie z odpowiedzią. – Onik

+0

miło, przyjrzę się ThreadPoolExecutor! :) – guisantogui

Powiązane problemy