ja używam Service
Class w systemie operacyjnym Android.
Planuję użyć Service
w tle.
Dokumentacja Androida stwierdza, że
Jeśli aplikacja jest kierowana na interfejs API na poziomie 26 lub wyższym, system nakłada ograniczenia na używanie lub tworzenie usług w tle, chyba że sama aplikacja jest na pierwszym planie. Jeśli aplikacja musi utworzyć usługę pierwszego planu, powinna zadzwonić
startForegroundService()
.
Jeśli użyjesz startForegroundService()
, Service
zgłasza następujący błąd.
Context.startForegroundService() did not then call
Service.startForeground()
Co jest z tym nie tak?
android
service
operating-system
foreground
android-8.0-oreo
Miły facet
źródło
źródło
Odpowiedzi:
Z dokumentów Google na temat zmian w zachowaniu Androida 8.0 :
Rozwiązanie: Zaproszenie
startForeground()
wonCreate()
dlaService
którego używaszContext.startForegroundService()
Zobacz także: Limity wykonywania w tle dla Androida 8.0 (Oreo)
źródło
onStartCommand
metodzie, ale wciąż pojawia się ten błąd. ZadzwoniłemstartForegroundService(intent)
do mnieMainActivity
. Być może usługa jest uruchamiana zbyt wolno. Myślę, że limit pięciu sekund nie powinien istnieć, zanim będą mogli obiecać, że usługa zostanie natychmiast uruchomiona.onStartCommand()
zamiast tegoonCreate
, ponieważ jeśli zamkniesz usługę i uruchomisz ją ponownie, może się udaćonStartCommand()
bez dzwonieniaonCreate
...dzwoniłem
ContextCompat.startForegroundService(this, intent)
aby uruchomić usługęCzynny
onCreate
źródło
onCreate
5 sekund. Powinni więc przeprojektować go, zanim zmuszą nas do przestrzegania zasad.StopService
po rozmowie telefonicznejstartForegroundService
.Przyczyną tego problemu jest to, że system Android nie może zagwarantować, że usługa zostanie uruchomiona w ciągu 5 sekund, ale z drugiej strony system ma ścisły limit powiadomień na pierwszym planie musi zostać uruchomiony w ciągu 5 sekund, bez sprawdzania, czy system próbował uruchomić usługę .
Jest to z pewnością kwestia ramowa, ale nie wszyscy programiści, którzy napotykają ten problem, starają się:
startForeground
powiadomienie musi być w obu przypadkach,onCreate
aonStartCommand
ponieważ jeśli twoja usługa jest już utworzona i jakoś twoja aktywność próbuje ją uruchomić ponownie,onCreate
nie zostanie wywołana.identyfikator powiadomienia nie może wynosić 0, w przeciwnym razie nastąpi taka sama awaria, nawet nie z tego samego powodu.
stopSelf
nie wolno wcześniej nazywaćstartForeground
.Przy wszystkich powyższych 3 problem ten można nieco zmniejszyć, ale nadal nie jest to poprawka, prawdziwa poprawka lub, powiedzmy, obejściem problemu jest obniżenie docelowej wersji SDK do 25.
I zauważ, że najprawdopodobniej Android P nadal będzie nosił ten problem, ponieważ Google nie chce nawet zrozumieć, co się dzieje i nie wierzy, że to ich wina, przeczytaj nr 36 i 56, aby uzyskać więcej informacji
źródło
startForeground
. Zmiana na 1 rozwiązuje problem (mam nadzieję)Wiem, że opublikowano już zbyt wiele odpowiedzi, jednak prawda jest taka - startForegroundService nie może zostać naprawiony na poziomie aplikacji i powinieneś przestać go używać. To zalecenie Google dotyczące korzystania z funkcji API # startForeground () w ciągu 5 sekund po wywołaniu kontekstu # startForegroundService () nie jest czymś, co aplikacja może zawsze zrobić.
Android uruchamia wiele procesów jednocześnie i nie ma żadnej gwarancji, że Looper wywoła usługę docelową, która ma wywołać startForeground () w ciągu 5 sekund. Jeśli usługa docelowa nie otrzyma połączenia w ciągu 5 sekund, nie będziesz miał szczęścia, a Twoi użytkownicy doświadczą sytuacji ANR. W śladzie stosu zobaczysz coś takiego:
Jak rozumiem, Looper przeanalizował tutaj kolejkę, znalazł „napastnika” i po prostu go zabił. System jest teraz szczęśliwy i zdrowy, a programiści i użytkownicy nie, ale skoro Google ogranicza swoje obowiązki do systemu, dlaczego mieliby się przejmować tymi dwoma ostatnimi? Najwyraźniej nie. Czy mogą to poprawić? Oczywiście, np. Mogliby wyświetlić okno dialogowe „Aplikacja jest zajęta”, prosząc użytkownika o podjęcie decyzji o czekaniu lub zabiciu aplikacji, ale dlaczego to przeszkadza, to nie jest ich odpowiedzialność. Najważniejsze, że system jest teraz zdrowy.
Z moich obserwacji wynika, że zdarza się to stosunkowo rzadko, w moim przypadku około 1 awarii w miesiącu dla 1 000 użytkowników. Reprodukcja jest niemożliwa, a nawet jeśli jest reprodukowana, nic nie możesz zrobić, aby to naprawić na stałe.
W tym wątku była dobra sugestia, aby użyć „wiązania” zamiast „startu”, a następnie, gdy usługa jest gotowa, należy przetworzyć onServiceConnected, ale znowu oznacza to, że w ogóle nie używa wywołań startForegroundService.
Myślę, że właściwym i uczciwym działaniem ze strony Google byłoby poinformowanie wszystkich, że startForegourndServcie ma wadę i nie należy go stosować.
Pozostaje pytanie: czego zamiast tego użyć? Na szczęście dla nas są teraz JobScheduler i JobService, które są lepszą alternatywą dla usług pierwszego planu. Jest to lepsza opcja, ponieważ:
Oznacza to, że nie musisz już martwić się obsługą wakelocków i dlatego nie różni się niczym od usług pierwszego planu. Z punktu widzenia implementacji JobScheduler nie jest twoją usługą, jest usługą systemową, prawdopodobnie dobrze poradzi sobie z kolejką, a Google nigdy nie zakończy własnego dziecka :)
Samsung przeszedł z startForegroundService na JobScheduler i JobService w swoim Samsung Accessory Protocol (SAP). Jest to bardzo pomocne, gdy urządzenia takie jak smartwatche muszą rozmawiać z hostami, takimi jak telefony, gdzie praca musi wchodzić w interakcję z użytkownikiem za pośrednictwem głównego wątku aplikacji. Ponieważ zadania są wysyłane przez program planujący do głównego wątku, staje się to możliwe. Powinieneś jednak pamiętać, że zadanie działa w głównym wątku i odciążyć wszystkie ciężkie rzeczy do innych wątków i zadań asynchronicznych.
Jedyną pułapką przejścia na JobScheduler / JobService jest to, że będziesz musiał przebudować stary kod i nie jest to zabawne. Ostatnie dwa dni spędziłem, robiąc to, aby skorzystać z nowej implementacji SAP nowego Samsunga. Będę oglądać moje raporty o awariach i dam ci znać, jeśli ponownie zobaczę awarie. Teoretycznie nie powinno się to zdarzyć, ale zawsze są szczegóły, o których możemy nie wiedzieć.
AKTUALIZACJA Żadnych awarii nie zgłoszono w Sklepie Play. Oznacza to, że JobScheduler / JobService nie mają takiego problemu, a przejście do tego modelu jest właściwym podejściem do pozbycia się problemu startForegroundService raz na zawsze. Mam nadzieję, że Google / Android to czyta i ostatecznie skomentuje / doradzi / zapewni oficjalne wskazówki dla wszystkich.
AKTUALIZACJA 2
Dla tych, którzy korzystają z SAP i pytają, w jaki sposób SAP V2 wykorzystuje JobService, wyjaśnienie znajduje się poniżej.
W niestandardowym kodzie musisz zainicjować SAP (to Kotlin):
Teraz musisz zdekompilować kod Samsunga, aby zobaczyć, co się dzieje w środku. W SAAgentV2 spójrz na implementację requestAgent i następujący wiersz:
Przejdź teraz do klasy SAAdapter i znajdź funkcję onServiceConnectionRequested, która planuje zadanie za pomocą następującego wywołania:
SAJobService to tylko implementacja Job'dervice dla systemu Android, a ta wykonuje harmonogram zadań:
Jak widzisz, ostatni wiersz tutaj używa Job'dchedulera na Androida, aby uzyskać tę usługę systemową i zaplanować zadanie.
W wywołaniu requestAgent przekazaliśmy mAgentCallback, która jest funkcją oddzwaniania, która przejmie kontrolę, gdy wydarzy się ważne zdarzenie. Oto jak funkcja zwrotna jest zdefiniowana w mojej aplikacji:
MessageJobs tutaj to klasa, którą zaimplementowałem, aby przetwarzać wszystkie żądania pochodzące od smartwatcha Samsung. To nie jest pełny kod, tylko szkielet:
Jak widać, MessageJobs wymaga również klasy MessageSocket, którą należy zaimplementować i która przetwarza wszystkie wiadomości przychodzące z urządzenia.
Podsumowując, nie jest to takie proste i wymaga trochę kopania do elementów wewnętrznych i kodowania, ale działa, a co najważniejsze - nie ulega awarii.
źródło
JobIntentService
działa natychmiast jakoIntentService
Oreo poniżej, ale planuje Zadanie w Oreo i powyżej, więcJobIntentService
nie uruchamia się natychmiast. Więcej informacjiJob...
uruchomienie zajmuje dużo czasu i jest to zaawansowana wersjaAlarmManager
.Aplikacja zawiesi się, jeśli zadzwonisz,
Context.startForegroundService(...)
a następnie zadzwoniszContext.stopService(...)
wcześniejService.startForeground(...)
.Mam jasne repro tutaj ForegroundServiceAPI26
Otworzyłem błąd na ten temat: Google tracker problemów
Kilka błędów w tym zakresie zostało otwartych i zamkniętych. Nie naprawi się.
Mam nadzieję, że moje z wyraźnymi krokami repro zrobi cięcie.
Informacje dostarczone przez zespół Google
Narzędzie do śledzenia problemów Google Komentarz 36
To nie jest błąd ramowy; to celowe. Jeśli aplikacja uruchamia wystąpienie usługi
startForegroundService()
, musi przenieść to wystąpienie usługi do stanu pierwszego planu i wyświetlić powiadomienie. Jeśli wystąpienie usługi zostanie zatrzymane przedstartForeground()
wywołaniem go, obietnica jest niespełniona: jest to błąd w aplikacji.Do nr 31 publikowanie usługi, którą inne aplikacje mogą uruchomić bezpośrednio, jest zasadniczo niebezpieczne. Możesz to nieco złagodzić, traktując wszystkie działania początkowe tej usługi jako wymagające
startForeground()
, choć oczywiście nie o to ci chodziło.Narzędzie do śledzenia problemów Google Komentarz 56
Istnieje kilka różnych scenariuszy, które prowadzą do tego samego rezultatu.
Bezpośredni problem semantyczny, polegający na tym, że po prostu błędem jest rozpoczęcie czegoś,
startForegroundService()
ale zaniedbanie przeniesienia go na pierwszy planstartForeground()
, jest taki: problem semantyczny. Celowo jest to traktowane jako błąd aplikacji. Zatrzymanie usługi przed przeniesieniem jej na pierwszy plan jest błędem aplikacji. To był sedno PO i dlatego kwestia ta została oznaczona jako „działająca zgodnie z przeznaczeniem”.Istnieją jednak pytania dotyczące fałszywego wykrywania tego problemu. Jest to traktowane jako prawdziwy problem, chociaż jest śledzone oddzielnie od tego konkretnego problemu ze śledzeniem błędów. Nie jesteśmy głusi na skargę.
źródło
Badałem to przez kilka dni i znalazłem rozwiązanie. Teraz w Androidzie O możesz ustawić ograniczenie tła, jak poniżej
Usługa wywołująca klasę usługi
i klasa usługi powinna być jak
źródło
Mam widżet który dokonuje stosunkowo częstych aktualizacji, gdy urządzenie nie działa i widziałem tysiące awarii w ciągu zaledwie kilku dni.
Wyzwalacz problemu
Nawet zauważyłem ten problem, nawet na moim Pixel 3 XL, kiedy nie sądziłem, że urządzenie w ogóle ma duże obciążenie. I wszystkie ścieżki kodu zostały pokryte
startForeground()
. Ale potem zdałem sobie sprawę, że w wielu przypadkach moja służba wykonuje pracę naprawdę szybko. Uważam, że przyczyną mojej aplikacji było zakończenie usługi, zanim system zaczął wyświetlać powiadomienia.Obejście / rozwiązanie
Byłem w stanie pozbyć się wszystkich awarii. To, co zrobiłem, to usunięcie połączenia z
stopSelf()
. (Myślałem o opóźnieniu zatrzymania, dopóki nie byłem prawie pewien, że powiadomienie zostało wyświetlone, ale nie chcę, aby użytkownik zobaczył powiadomienie, jeśli nie jest konieczne.) Gdy usługa była bezczynna przez minutę lub system niszczy go normalnie, nie zgłaszając żadnych wyjątków.źródło
Tylko jedna głowa, ponieważ zmarnowałem na to zbyt wiele godzin. Cały czas otrzymywałem ten wyjątek, mimo że dzwoniłem
startForeground(..)
jako pierwszyonCreate(..)
. W końcu odkryłem, że problem był spowodowany użyciemNOTIFICATION_ID = 0
. Wydaje się, że użycie jakiejkolwiek innej wartości to naprawić.źródło
Mam rozwiązanie tego problemu. Sprawdziłem tę poprawkę we własnej aplikacji (300 KB + DAU), która może zmniejszyć co najmniej 95% tego rodzaju awarii, ale nadal nie mogę w 100% uniknąć tego problemu.
Ten problem występuje nawet wtedy, gdy wywołujesz funkcję startForeground () zaraz po uruchomieniu usługi zgodnie z dokumentacją Google. Może się tak zdarzyć, ponieważ proces tworzenia i inicjowania usługi kosztuje już ponad 5 sekund w wielu scenariuszach, bez względu na to, kiedy i gdzie wywołasz metodę startForeground (), ta awaria jest nieunikniona.
Moim rozwiązaniem jest upewnienie się, że startForeground () zostanie wykonany w ciągu 5 sekund po metodzie startForegroundService (), bez względu na to, jak długo twoja usługa musi zostać utworzona i zainicjowana. Oto szczegółowe rozwiązanie.
Nie używaj startForegroundService w pierwszej kolejności, użyj bindService () z flagą auto_create. Będzie czekać na inicjalizację usługi. Oto kod, moja przykładowa usługa to MusicService:
Oto implementacja MusicBinder:
Najważniejsza część, implementacja MusicService, forceForeground () zapewni, że metoda startForeground () zostanie wywołana zaraz po startForegroundService ():
Jeśli chcesz uruchomić fragment kodu z kroku 1 w zamierzonym celu, na przykład jeśli chcesz uruchomić usługę pierwszego planu w widżecie (kliknij przycisk widgetu) bez otwierania aplikacji, możesz owinąć fragment kodu w odbiorniku emisji i uruchom zdarzenie rozgłoszeniowe zamiast polecenia uruchomienia usługi.
To wszystko. Mam nadzieję, że to pomoże. Powodzenia.
źródło
Ten błąd występuje również w Androidzie 8+, gdy Service.startForeground (int id, powiadomienie) jest wywoływany, gdy id jest ustawiony na 0.
źródło
Ponieważ wszyscy tutaj odwiedzający cierpią z tego samego powodu, chcę podzielić się moim rozwiązaniem, którego nikt wcześniej nie próbował (w każdym razie w tym pytaniu). Zapewniam cię, że działa, nawet po zatrzymaniu punktu przerwania który potwierdza tę metodę.
Problemem jest zadzwonić
Service.startForeground(id, notification)
z samej usługi, prawda? Android Framework niestety nie gwarantuje zadzwonieniaService.startForeground(id, notification)
w ciąguService.onCreate()
5 sekund, ale i tak zgłasza wyjątek, więc wymyśliłem ten sposób.Context.startForegroundService()
Context.startForegroundService()
z połączenia serwisowego i natychmiast zadzwońService.startForeground()
w ramach połączenia serwisowego.Context.bindService()
metodę wewnątrz try-catch, ponieważ w niektórych przypadkach wywołanie może zgłosić wyjątek, w którym to przypadku musisz polegać naContext.startForegroundService()
bezpośrednim wywołaniu i mieć nadzieję, że nie zawiedzie. Przykładem może być kontekst odbiornika rozgłoszeniowego, jednak uzyskanie kontekstu aplikacji nie rzuca wyjątku w tym przypadku, ale bezpośrednie użycie kontekstu.Działa to nawet, gdy czekam na punkcie przerwania po powiązaniu usługi i przed wywołaniem wywołania „startForeground”. Oczekiwanie między 3-4 sekundami nie wyzwala wyjątku, a po 5 sekundach powoduje wyjątek. (Jeśli urządzenie nie może wykonać dwóch linii kodu w ciągu 5 sekund, nadszedł czas, aby wyrzucić to do kosza.)
Zacznij więc od utworzenia połączenia serwisowego.
Wewnątrz usługi utwórz segregator, który zwróci wystąpienie usługi.
Następnie spróbuj powiązać usługę z tego kontekstu. Jeśli się powiedzie, wywoła
ServiceConnection.onServiceConnected()
metodę z połączenia usługi, którego używasz. Następnie obsłuż logikę w powyższym kodzie. Przykładowy kod wyglądałby tak:Wygląda na to, że działa na opracowywanych przeze mnie aplikacjach, więc powinien działać również przy próbie.
źródło
Problem z Androidem O API 26
Jeśli zatrzymasz usługę od razu (więc Twoja usługa tak naprawdę nie działa (sformułowanie / rozumienie) i jesteś znacznie poniżej przedziału ANR, nadal musisz wywołać startForeground przed stopSelf
https://plus.google.com/116630648530850689477/posts/L2rn4T6SAJ5
Próbowałem tego podejścia, ale nadal powoduje błąd: -
Używam tego, dopóki błąd nie zostanie rozwiązany
źródło
Mam ten sam problem i po spędzeniu czasu na znalezieniu rozwiązania możesz wypróbować poniższy kod. Jeśli używasz,
Service
umieść ten kod w polu onCreate, jeśli używasz,Intent Service
umieść ten kod w polu onHandleIntent.źródło
Badałem ten problem i właśnie to odkryłem. Ta awaria może się zdarzyć, jeśli mamy kod podobny do tego:
MyForegroundService.java
MainActivity.java
Wyjątek jest zgłaszany w następującym bloku kodu:
ActiveServices.java
Metoda ta jest wykonywana przed
onCreate()
wśródMyForegroundService
ponieważ harmonogramy Android tworzenia służby na głównej obsługi wątku, alebringDownServiceLocked
nazywa się na zasadzieBinderThread
, wich jest sytuacja wyścigu. Oznacza to, żeMyForegroundService
nie miałem okazji zadzwonićstartForeground
co spowoduje awarię.W tym celu musimy się upewnić, że ustalenie
bringDownServiceLocked
nie jest wywoływana przedonCreate()
oMyForegroundService
.Za pomocą transmisji trwałych mamy pewność, że program nie zgubić i
stopReceiver
odbiera przystanek zamiaru tak szybko, jak to zostało zarejestrowane wonCreate()
odMyForegroundService
. Do tego czasu już dzwoniliśmystartForeground(...)
. Musimy również usunąć tę lepką transmisję, aby następnym razem nie powiadomić stopReceiver.Należy pamiętać, że metoda
sendStickyBroadcast
jest przestarzała i używam jej tylko jako tymczasowego obejścia tego problemu.źródło
Tak wiele odpowiedzi, ale żadna nie działała w moim przypadku.
Rozpocząłem taką usługę.
I w mojej usłudze onStartCommand
I nie zapomnij ustawić NOTIFICATION_ID na zero
Więc wszystko było idealne, ale wciąż zawiesza się na 8.1, więc przyczyną było jak poniżej.
Zadzwoniłem do zatrzymania pierwszego planu z usunięciem powiadomienia, ale po usunięciu powiadomienia usługa staje się tłem, a usługa w tle nie może działać w Androidzie O z tła. rozpoczęty po otrzymaniu wypychania.
Tak magiczne słowo brzmi
Jak dotąd, z jakiegokolwiek powodu awarii usługi, wykonaj wszystkie powyższe kroki i ciesz się.
źródło
startForeground
należy się wzywaćonCreate
?https://developer.android.com/reference/android/content/Context.html#startForegroundService(android.content.Intent)
upewnij się, że wywołujesz funkcję
Service.startForeground(int, android.app.Notification)
onCreate (), więc upewnisz się, że zostanie ona wywołana .. jeśli masz jakieś warunki, które mogą Ci to uniemożliwić, lepiej skorzystaj z normalnegoContext.startService(Intent)
i zadzwoń doService.startForeground(int, android.app.Notification)
siebie.Wygląda na to, że
Context.startForegroundService()
dodaje strażnika, aby upewnić się, że zadzwoniłeś,Service.startForeground(int, android.app.Notification)
zanim został zniszczony ...źródło
Proszę nie wywoływać żadnych StartForgroundServices w metodzie onCreate () , musisz wywołać usługi StartForground w onStartCommand () po utworzeniu wątku roboczego, w przeciwnym razie zawsze otrzymasz ANR, więc nie pisz skomplikowanego logowania w głównym wątku onStartCommand () ;
EDYCJA: Uwaga! Funkcja startForeground nie może przyjąć 0 jako pierwszego argumentu, spowoduje wyjątek! ten przykład zawiera nieprawidłowe wywołanie funkcji, zmień 0 na własną stałą, która nie może być równa 0 lub większa niż Max (Int32)
źródło
Nawet po wywołaniu
startForeground
inService
, on awarii na niektórych urządzeniach, jeżeli nazywamystopService
tuż przedonCreate
nazywa. Rozwiązałem ten problem, uruchamiając usługę z dodatkową flagą:i dodał check onStartCommand, aby sprawdzić, czy zaczął się zatrzymywać:
PS Gdyby usługa nie była uruchomiona, najpierw uruchomiłaby usługę, co jest narzutem.
źródło
Musisz dodać pozwolenie poniżej dla urządzenia z systemem Android 9, gdy używasz docelowego pakietu SDK 28 lub nowszego, w przeciwnym razie wyjątek zawsze się zdarza:
źródło
Sprawdzam tylko
PendingIntent
zero lub nie przed wywołaniemcontext.startForegroundService(service_intent)
funkcji.to działa dla mnie
źródło
wystarczy wywołać metodę startForeground natychmiast po utworzeniu usługi lub usługi IntentService. lubię to:
źródło
Ok, zauważyłem coś, co może pomóc również kilku innym. Jest to ściśle z testowania, czy mogę wymyślić, jak naprawić zdarzenia, które widzę. Dla uproszczenia, powiedzmy, że mam metodę, która wywołuje to od prezentera.
To się zawiesi z tym samym błędem. Usługa NIE uruchomi się, dopóki metoda nie zostanie zakończona, dlatego nie
onCreate()
w usłudze.Więc nawet jeśli zaktualizujesz interfejs użytkownika poza głównym wątkiem, JEŻELI masz coś, co może zatrzymać tę metodę po nim, nie uruchomi się on na czas i da ci przerażający błąd na pierwszym planie. W moim przypadku ładowaliśmy niektóre rzeczy do kolejki i każda z nich była wywoływana
startForegroundService
, ale w tle działała pewna logika. Jeśli więc logika zajęła zbyt dużo czasu, aby ukończyć tę metodę, ponieważ były one wywoływane jeden po drugim, czas awarii. StarystartService
po prostu zignorował to i poszedł dalej, a ponieważ dzwoniliśmy za każdym razem, następna runda dobiegała końca.Zastanawiałem się, czy jeśli zadzwonię do usługi z wątku w tle, czy nie można go całkowicie związać na starcie i uruchomić natychmiast, więc zacząłem eksperymentować. Mimo że NIE uruchamia się to natychmiast, nie ulega awarii.
Nie będę udawać, że wiem, dlaczego nie ulega awarii, chociaż podejrzewam, że zmusza to do czekania, aż główny wątek poradzi sobie z tym w odpowiednim czasie. Wiem, że nie jest idealne wiązanie go z głównym wątkiem, ale ponieważ moje użycie wywołuje go w tle, nie martwię się, czy czeka, aż będzie w stanie zakończyć, a nie zawiesić.
źródło
Dodaję kod w @humazed odpowiedzi. Więc nie ma wstępnego powiadomienia. To może być obejście, ale działa dla mnie.
Po powiadomieniu dodaję transparentColor w małej ikonie i kolorze. To będzie działać.
źródło
Rozwiązałem problem z uruchamianiem usługi
startService(intent)
zamiast zamiastContext.startForeground()
dzwonieniemstartForegound()
natychmiast po niejsuper.OnCreate()
. Ponadto, jeśli uruchamiasz usługę podczas rozruchu, możesz uruchomić działanie, które uruchamia usługę w rozgłaszaniu rozruchu. Chociaż nie jest to trwałe rozwiązanie, działa.źródło
Aktualizowanie danych w
onStartCommand(...)
onBind (...)
onBind(...)
jest lepsza impreza cyklu zainicjowaćstartForeground
Vs.onCreate(...)
ponieważonBind(...)
przechodzi wIntent
które mogą zawierać ważne dane wBundle
potrzebne do zainicjowaniaService
. Nie jest to jednak konieczne, ponieważonStartCommand(...)
jest wywoływane przy pierwszymService
utworzeniu lub wywoływane później.onStartCommand (...)
startForeground
wonStartCommand(...)
ważne jest, aby zaktualizowaćService
raz już zostało stworzone.Kiedy
ContextCompat.startForegroundService(...)
jest wywoływany poService
utworzeniuonBind(...)
ionCreate(...)
nie jest wywoływany. W związku z tym zaktualizowane dane mogą być przekazywaneonStartCommand(...)
za pośrednictwemIntent
Bundle
do aktualizacji danych wService
.Próba
Używam tego wzorca, aby zaimplementować
PlayerNotificationManager
w aplikacji wiadomości kryptowaluty Coinverse .Activity / Fragment.kt
AudioService.kt
źródło
Usługa
Próbnik
Wynik
źródło