Service

Transkrypt

Service
Programowanie usług
działających w tle
Android
Paweł Szafer
Po co programować usługi działające w
tle?
Plan prezentacji
● O aplikacjach w Androidzie,
● Sposób podejmowania decyzji o zabiciu procesu,
● Rodzaje procesów,
● Wątki,
● AsyncTask,
● Services,
○ Service,
■ unbound,
■ bound,
○ IntentService,
● Współdzielenie danych - ContentProvider,
● Komunikacja między procesami - BroadcastReceiver.
Aplikacje
● Domyślnie wszystkie aplikacje działają w obrębie tego
samego procesu,
● Android może zdecydować o zabiciu aplikacji, gdy nie ma
wystarczającej ilości pamięci dla aplikacji ważniejszej
i/lub obsługującej użytkownika,
● Wszystkie komponenty aplikacji są niszczone (wywoływana
metoda onDestroy() ).
Podejmowanie decyzji o zabiciu
aplikacji
W przypadku konieczności zabicia aplikacji tworzony jest
ranking znaczenia aplikacji, tworzony w oparciu o:
● rodzaj komponentów działających w obrębie aplikacji,
● stan komponentów działających w obrębie aplikacji,
Na podstawie powyższych danych tworzony jest ranking
procesu. Im wyższy wynik tym mniej prawdopodobne zabicie
aplikacji.
Rodzaje procesów
1. Foreground process,
○ Activity,
○ Service odwołujący się do Activity, które użytkownik
aktualnie używa,
○ Service, który został uruchomiony poprzez wywołanie
metody startForeground(),
○ Service, który jest w jednej z następujących metod:
■ onCreate(),
■ onStart(),
■ onDestroy().
Ta kategoria prawie nigdy nie jest skierowana do zabicia.
Rodzaje procesów
2. Visible process - proces, który nie posiada żadnych
elementów pierwszego planu (widocznych na ekranie), ale
może wpływać na zawartość ekranu użytkownika np.
● Activity, które jest w metodzie onPause() (w tle),
● Service, który współpracuje z Acitivty (będące procesem
pierwszoplanowym lub widocznym).
Procesy w tej kategorii są ekstremalnie ważne, a task killer w
przypadku, gdy musi któryś z nich zabić, stara się zawsze
poczekać aż zakończą one swoje działania.
Rodzaje procesów
3. Service
● proces, który implementuje klasę Service,
● rozpoczęty poprzez wywołanie metody startService(),
● nie może zostać zakwalifikowany do żadnej z
wcześniejszych kategorii,
● użytkownik nie może widzieć jego działania,
● Przykład: odtwarzanie muzyki, pobieranie danych z sieci.
Rodzaje procesów
4. Background process:
● Activity, które nie jest aktualnie widoczne na ekranie
(zatrzymane poprzez wywołanie onStop()),
● mogą zostać zatrzymane w każdym momencie działania,
jeżeli system widzi taką potrzebę (np. zajmowanie
pamięci dla procesów pierwszoplanowych, zbyt duże
obciążenie procesora).
Rodzaje procesów
5. Empty process
● aplikacja, która nie posiada żadnych aktywnych
komponentów,
● jedyny powód dla systemu, aby działała:
w celu cache'owania, aby przy kolejnym uruchomieniu
aplikacja mogła szybciej zostać uruchomiona.
Rodzaje procesów - podsumowanie
2 sytuacje:
● Wątek wywołany z Activity jest traktowany jako proces tła
(4),
● Service wywołany z Activity ma ranking 3.
Oznacza to, że lepiej uruchomić service, niż wątek (Activity,
może oczekiwać w tle na zakończenie operacji wątku, który
został zabity).
Worker threads
Zasady:
● nigdy nie blokuj wątku interfejsu użytkownika,
● nie próbuj dostać się do komponentów wątku interfejsu
użytkownika spoza niego.
Po około 5 sekundach braku odpowiedzi z Activity pojawia się
komunikat o braku odpowiedzi aplikacji.
W związku z tym nie można (z kilkoma wyjątkami) wywoływać
blokujących operacji wewnątrz interfejsu użytkownika
Worker threads
Źle
Zasada: nie próbuj dostać się do komponentów wątku interfejsu
użytkownika spoza niego.
Worker threads
Aby umożliwić modyfikowanie elementów interfejsu
użytkownika wykorzystuje się metody:
● Activity.runOnUiThread(Runnable),
● View.post(Runnable),
● View.postDelayed(Runnable, long).
AsyncTask<Void, Void, Void>
● Przeznaczone do wywołania operacji asynchronicznych z
poziomu interfejsu użytkownika,
● zadanie może być wywołane tylko jeden raz,
● posiada metody do interakcji z UI (onProgressUpdate()),
● gdy Activity przechodzi do działania w tle, w
AsyncTask wywoływana jest metoda doInBackground(),
wówczas AsyncTask ma ranking 4 (background process).
Services
● klasa bazowa dla wszystkich Service,
● komponent aplikacji wykonujący długotrwałe operacje w
tle, nie posiadający interfejsu użytkownika.
● aplikacja główna może zostać zamknięta, a service może
nadal działać,
● inne aplikację mogą zarządzać usługą (np. w celu
wyłączenia odtwarzania muzyki).
Podział service's
Started (unbound) - usługa uruchomiona poprzez
wywołanie metody startService(). ● usługa może działać w tle dowolną ilość czasu, nawet gdy
komponent ją uruchamiający został zabity, ● Service nie powinien zwracać wyników operacji do
wywołującego ją komponentu,
● powinien sam się zatrzymać po wykonaniu operacji,
● dla każdej większej operacji powinien być zaprojektowany
oddzielny Service (wiele czynności wykonywanych
wewnątrz jednej usługi może zabierać za dużo pamięci i
być w gorszej sytuacji w przypadku szukania procesu do
zabicia przez system).
Podział service's
Bound - service jest powiązany, gdy jest wywołana poprzez
metodę bindService(). Bound Service oferuje interfejs typu
klient - serwer, dzięki któremu wiele komponentów może się
z nią komunikować. Pozwala na:
● wysyłanie żądań,
● pobieranie wyników,
● umożliwia komunikację między kilkoma procesami.
Ten rodzaj usługi działa tak długo, aż jakikolwiek proces jest
do niej podłączony. Naraz, standardowo może być podłączona
dowolna ilość procesów.
Podział service's
Oba rodzaje tj. Started i Bound mogą być zaimplementowane
w jednej usłudze.
Service również podlega pod systemowe sprawdzanie czy
aplikacja nie została zawieszona (Application Not Responding
error), co oznacza, że w przypadku operacji blokujących lub
mających duże zapotrzebowanie na czas procesora wewnątrz
usługi powinien być zaimplementowany oddzielny wątek na
ich wykonanie.
Service - implementacja
IntentService
● klasa wywodząca się z Service,
● sama uruchamia wątek wywołujący żądanie,
● IntentService nie obsługuję wielokrotnego, współbieżnego
wywołania (tylko jeden wątek w tym samym czasie),
● główna zaleta - konieczność zaimplementowania jednej
metody onHandleIntent().
IntentService - implementacja
Zarządzanie współdzielonymi danymi
● ContentProvider - zarządza współdzielonymi danymi. Dane
mogą być przechowywane w sieci, w bazie danych SQLite.
Implementuje metody do zarządzania współdzielonymi
danymi (np. insert, query, delete, update),
● ContentResolver - zapewnia komunikację aplikacji z
ContentProvider'em. Zazwyczaj nie jest konieczny do
samodzielnej implementacji
Żadna z powyższych klas nie implementuje interfejsu
użytkownika.
Zarządzanie współdzielonymi danymi
● ContentObserver - informuje zarejestrowane aplikację o
zmianie danych przez ContentProvider'a,
● DataSetObserver - informuję o wywołaniu metody w
ContentResolver, czyli również o odczycie danych i próbie
dostępu (nawet jeżeli jest nieudana).
Żadna z powyższych klas nie implementuje interfejsu
użytkownika.
Komunikacja między
procesami/aplikacjami
BroadcastReceiver:
● służy do rozgłaszania informacji np. Service może
poinformować aplikację o zakończeniu pobierania,
● nie implementuje interfejsu użytkownika,
● może stworzyć powiadomienie na pasku powiadomień,
● zazwyczaj służy jedynie jako brama do komunikacji między
komponentami np. w przypadku wystąpienia określonego
wydarzenia może uruchomić zdefiniowany Service.
KONIEC
Materiały:
● http://developer.android.com

Podobne dokumenty