Im bardziej w las tym więcej drzew. Podobnie jest z aplikacjami na androida, im bardziej rozbudowana aplikacja tym więcej funkcji. W tym gąszczu funkcji na pewno są serwisy, które wykonują różnorakie rzeczy, np aktualizacja informacji. O ile stworzenie powiadomień nie jest trudne to aktualizacja aktywności może już spowodować pewne problemy. W jaki sposób przekazać dane z serwisu do aktywności dane? Dziś postaram się odpowiedzieć na to pytanie w jaki sposób przekazywać dane. W tej części pokaże Ci podstawowe metody komunikacji między serwisem a aktywnością w androidzie, w drugiej części znajdziesz metody bardziej zaawansowane.

1. Założenia.

Aby lepiej zrozumieć komunikację przedstawię założenia projektu.  Mamy serwis, który co sekundę zwiększa liczbę o 1. Nasz serwis może wyglądać tak:

Teraz musimy przesłać mConuter z serwisu do aktywności. Natomiast z aktywności zatrzymujemy liczenie.

2. Skorzystaj z Intenta.

Najprostsza forma przekazywania danych między aktywnościami, ale także między service a activity to skorzystanie z Intenta. Aby wysłać informacje o zatrzymaniu liczenia, z aktywności wykonujemy taki kod:

Aby odebrać dane z intencji w serwisie to w metodzie onStartCommand() dodajemy:

Jeszcze pozostało nam poinformowanie aktywności o liczbie. W serwisie w pętli while dodajemy:

Zaś w aktywności odbieramy intencję w ten sposób:

Użyj tej metody, jeśli przekazujesz prymitywne dane. Możesz także przekazywać obiekty, które implementuje Serializable. Serializable niestety jest wolny dlatego lepszym rozwiązaniem jest skorzystanie z Parcelable (sporo kodu do pisania). Kolejną wadą tej metody jest to, że aktywność będzie tworzona na nowo lub wznawiana w zależności od cyklu życia aktywności. Tą metodę warto stosować gdy faktycznie musimy wyświetlić ekran po zakończeniu działania jakiejś czynności. No chyba, że preferujesz lepszą praktykę i skorzystasz z powiadomień. Jeżeli masz bardziej złożone obiekty i chcesz jednak skorzystać z intencji to użyj gson, aby przekształcić obiekt w JSON.

3. Statyczna metoda, zmienna.

Innym sposobem poinformowania serwisu o zaprzestaniu liczenia jest stworzenie statycznej metody lub zmiennej. W aktywności wywołujemy taki kod:

A w serwisie tworzymy taką metodę:

Wtedy naszą zmienną musimy zmienić na statyczną:

Nic nie stoi na przeszkodzie abyśmy zrobili ją publiczną i zmieniali wartość bezpośrednio w aktywności.

Minus tego rozwiązania będzie tworzenie geterów i seterów – kiepskie rozwiązanie. Na pewno ten sposób nie jest bezpieczny, ale już lepiej ponieważ aktywność nie jest wielokrotnie „przetwarzana”.

Oczywiście też możesz wysłać instancję aktywności przez Intent i odwołać się do metod prywatnych, ale czy to ma sens? Wątpię, są o wiele lepsze metody.

4. Podłącz się do serwisu.

Najczęstszym sposobem i też bezpiecznym jest podłączenie się do usługi. Jeśli Twoja usługa jest używana przez lokalną aplikację i nie musi pracować pomiędzy procesami, możesz zaimplementować własną klasę Binder, która zapewnia klientowi (aktywności) bezpośredni dostęp do publicznych metod w usłudze. Dodajmy do naszej usługi taki kod:

Binder wykonuje jedną z następujących czynności:

  • Zawiera publiczne metody, które może wywoływać klient,
  • Zwraca bieżącą instancję usługi, która ma publiczne metody i może je wywołać klient,
  • Zwraca instancję innej klasy hostowanej przez usługę i posiada również publiczne metody, które mogą być wywołane przez klienta.

Teraz zobacz jak zastosować to w klasie z aktywnością:

Aby podłączyć się do usługi i wywołać zatrzymanie liczenia robisz tak:

Podłączając się do usługi, metoda getService() zwraca instancję usługi. Jak już mamy taki obiekt możemy wywoływać publiczne metody, które znajdują się w usłudze. Kod powyższy pozwala Ci sterować z poziomu aktywności usługą. Natomiast jeśli chcesz uzyskać informację od serwisu o liczbie możesz zastosować implementacje interfejsu. W usłudze dodaj taki kod:

W klasie LocalBinder dodaj metodę:

Teraz w aktywności w metodzie onServiceConnected() pobierz callback’a:

I jeszcze implementacja:

Ok, masz teraz komunikację serwisem a aktywnością i odwrotnie. Pamiętaj, że usługa i klient muszą znajdować się w tej samej aplikacji.

5. BroadcastReceiver.

Jeszcze innym sposobem na komunikację miedzy serwisem a aktywnością jest BroadcastReceiverTa metoda przydaje się gdy chcemy nadsłuchiwać zdarzeń w systemie, a serwis te zdarzenia przetwarza na przykład sprawdza wiadomości gdy internet jest dostępny. Mamy dwa rodzaje rejestracji receivera: statycznie przez plik manifestu oraz dynamicznie w kodzie. Poniżej zobaczysz przykład broadcastreceiver zarejestrowanego dynamicznie. Będzie działać tylko wtedy gdy aplikacja będzie działać. W usłudze dodajemy:

W metodzie onCreate() wywołaj setupReceiver(). Jeżeli chcesz wyrejestrować to wywołujesz:

Natomiast w aktywności wywołujesz zatrzymanie liczenia w ten sposób:

Szybkie i proste, prawda? Masz teraz komunikację aktywność –> serwis. Aby z serwisu pobierać dane robisz podobnie tylko w drugą stronę. Ze względu na pewne ograniczenia wprowadzone w Android O zalecam korzystanie z dynamicznych broadcasterów.

6. Inne Metody.

Oprócz wyżej wymienionych metod możesz jeszcze skorzystać z takich opcji jak:

O ile powyższe metody są ok, to ich zastosowanie jest nie zawsze poprawne. Ponieważ w aktywności i serwisie musiałbyś zaimplementować odczytywanie tych wartości co jakiś określony czas, w powyższym przypadku co sekundę. Więc te metody nie zawsze mogą się sprawdzić pod względem wydajności. Pamiętaj o tym też, że system Android może unicestwić aktywnoś

7. Podsumowanie.

To nie koniec metod komunikacji między serwisem a aktywnością w androidzie. Jest jeszcze sporo innych, tutaj ogranicza nas tylko wyobraźnia. Gdybym chciał Ci przedstawić wszystkie wpis byłby ogromy, dlatego uznałem, że podzielę to zagadnienie na dwie części. W tej części przedstawiłem tylko podstawowe i najczęściej spotykane metody. W kolejnej części poznasz bardziej zaawansowane metody.

Pamiętaj, że to od Ciebie i Twojego projektu zależy, który sposób wykorzystasz. Nie ma jednej uniwersalnej metody komunikacji między serwisem a aktywnością w androidzie.

Mam nadzieje, że Ci pomogłem. Proszę Cię również o udostępnienie tego wpisu innym osobą, na przykład przez media społecznościowe. Będę Ci za to bardzo wdzięczny. Dzięki!

Miłego dnia i miłego kodowania 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *