Jak wymusić restart usługi?

Mam usługę w tle, która czasami zostaje zabita przez system operacyjny, gdy kończy mu się pamięć.

  1. Jak zasymulować to zachowanie, aby móc je debugować?

Poradnik dewelopera po prostu mówi: "jeśli Twoja usługa jest uruchomiona, musisz ją zaprojektować tak, aby z wdziękiem obsługiwała ponowne uruchomienie przez system. Jeśli system zabije twoją usługę, uruchomi ją ponownie, gdy tylko zasoby staną się ponownie dostępne".

  1. Jaka jest sekwencja połączeń od kiedy zostaje zabity do kiedy kończy ponowne uruchomienie?

Na stronie (powiązane) pytanie, co się dzieje z aktywnie działającym AsyncTask uruchomionym w usłudze, gdy usługa zostanie zabita przez system operacyjny, tzn. bez usługi.dzwonili do ondestroya? Czy nadal działa, czy jest zgrywany po cichu wraz z usługą?

Author: jaysoifer, 2011-08-31

2 answers

W nowszych wersjach usługa będzie miała wywołane następujące zdarzenia:

onCreate()

Następnie...

int onStartCommand(Intent intent, int flags, int startid)

Wiem, że w komentarzach wspomniałeś o tym, ale warto powtórzyć: nie używaj starego zdarzenia " onStart ()". onStartCommand to nowy sposób działania.

OnCreate () może być użyte do tworzenia dowolnych obiektów, itd. ale wykonaj rzeczywisty kod swojej usługi w onStartCommand().

Po zakończeniu z onstartcommand () powinieneś zwrócić wynik. Użycie "START_STICKY" mówi systemowi, że może się zrestartować, jeśli będzie musiał go zabić. Użycie "START_NOT_STICKY"mówi systemowi, aby nie trudził się ponownym uruchomieniem go po ponownym uruchomieniu pamięci. Oznacza to, że aplikacja musiałaby ponownie ręcznie uruchomić usługę. Są też inne opcje-sprawdź dokumenty API.

Sprawdzenie tych flag pozwoli Ci sprawdzić, dlaczego Twoja usługa została uruchomiona - jeśli uruchomiła ją twoja własna aplikacja lub jeśli uruchomił ją system operacyjny, aby ją ponownie uruchomić. Będziesz trzeba okresowo przechowywać stan wszelkich ważnych zmiennych, aby Jeśli system operacyjny został ponownie uruchomiony, można je odzyskać - prawdopodobnie można użyć SharedPreferences private storage do przechowywania tych. Zdecydowanie przechowuj jakiekolwiek w wydarzeniu onDestroy, ale nie licz na to, że zostanie wywołany.

Zaleca się również przechowywanie pola startID w zmiennej i używanie go z stopSelfResult (startId), gdy usługa jest uruchomiona.

Należy pamiętać, że jeśli usługa jest zabijana przez system operacyjny możesz nie mieć możliwości przechowywania żadnych zmiennych. musisz być w stanie zobaczyć, czy twój stan jest tam, gdzie się spodziewasz po ponownym uruchomieniu przez system operacyjny, a jeśli nie po prostu zresetuj wszystko lub zgiń z wdziękiem.

Jeśli chodzi o debugowanie, czy rozważałeś napisanie innej aplikacji, która tylko wysysa pamięć w aktywności, aby wymusić niski stan pamięci? Top aktywność powinna uzyskać pierwszeństwo do pamięci i wymusić usługę do giń.

Dodatkowe wątki uruchomione w usłudze są nadal częścią tego samego procesu aplikacji, więc zostaną zabite wraz z usługą (i resztą aplikacji.) Możesz to zweryfikować dodając regularne instrukcje logu wewnątrz wątków, a następnie zabijając usługę.

Inną rzeczą, która może być dla Ciebie przydatna, jest sprawdzenie, czy usługa jest już uruchomiona z poziomu aplikacji. Oto funkcja, która to zrobi:

// Determine if one of my services is currently running
public static boolean isMyServiceRunning(Context context, String servicename) {
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (servicename.equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}
 6
Author: Tony Maro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-07 20:52:16

Jeśli jest to Usługa lokalna (domyślna), w przeciwieństwie do usługi zdalnej, to działa w tym samym procesie co aplikacja. Oznacza to, że można emulować zabijanie go, po prostu zabijając proces aplikacji. Możesz to zrobić używając ddms na przykład w eclipse lub z linii poleceń, a nawet z telefonu (Ustawienia -> Aplikacje).

 3
Author: Erdal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-31 21:25:58