Na tej stronie omawiamy niektóre typowe przyczyny niepowodzenia działania usług na pierwszym planie i pomagamy zidentyfikować przyczynę problemu.
W tym dokumencie omawiamy te kwestie:
Zanim zaczniesz rozwiązywać problem
Sprawdzanie ostatnich zmian w usługach na pierwszym planie
Nieprawidłowe użycie usług działających na pierwszym planie może negatywnie wpłynąć na wydajność urządzenia i czas pracy na baterii. Dlatego w wersjach platformy Android często wprowadzamy zmiany w działaniu usług działających na pierwszym planie, aby ograniczyć te negatywne skutki.
Jeśli masz problemy z usługami na pierwszym planie, zapoznaj się z dokumentacją zmian w usługach na pierwszym planie i sprawdź, czy nie ma w niej ostatnich zmian, które mogłyby wyjaśnić Twoje problemy. W szczególności warto sprawdzać zmiany w tych okolicznościach:
- Kod usługi na pierwszym planie, który wcześniej działał, teraz nie działa
- testowanie rozpoczęło się na nowej wersji platformy lub zmieniono poziom interfejsu API, na który jest ukierunkowana aplikacja;
Jeśli testujesz urządzenie w wersji przedpremierowej platformy dla programistów, zapoznaj się z najnowszą wersją dokumentacji wersji przedpremierowej dla programistów.
Błędy typu „Aplikacja nie odpowiada” (ANR)
W pewnych okolicznościach aplikacja powinna zamknąć usługę na pierwszym planie. Jeśli aplikacja nie zatrzyma usługi, system ją zatrzyma i wywoła błąd Aplikacja nie odpowiada (ANR).
Krótka usługa działa zbyt długo, co powoduje błąd ANR
Usługi działające na pierwszym planie, które używają typu krótkiej usługi, muszą zakończyć się szybko, w ciągu około 3 minut. Gdy czas się skończy, system wywoła metodę Service.onTimeout(int,int)
usługi. Usługa ma kilka sekund na wywołanie funkcji stopSelf()
. Jeśli usługa nie zatrzyma się sama, system wywoła błąd ANR.
Diagnozowanie:
Jeśli błąd ANR został spowodowany przez usługę działającą na pierwszym planie, która nie mogła się zatrzymać, system zgłasza wewnętrzny wyjątek. Możesz to sprawdzić w raportach ANR. Jeśli to jest problem, w raporcie pojawi się ten komunikat:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type FOREGROUND_SERVICE_TYPE_SHORT_SERVICE did not stop within its timeout:
[component name]"
Rozwiązanie:
Upewnij się, że wszystkie usługi na pierwszym planie z ograniczeniem czasowym kończą pracę i wywołują stopForeground(int)
w ramach limitu czasu systemowego.
Usługi działające na pierwszym planie muszą implementować interfejs Service.onTimeout(int,int)
.
Upewnij się, że implementacja tej metody od razu wywołuje funkcję stopSelf()
.
Wyjątki dotyczące usług działających na pierwszym planie
W tej sekcji opisujemy kilka problemów z usługami działającymi na pierwszym planie, które mogą powodować zgłaszanie przez system wyjątku. Jeśli aplikacja nie przechwyci wyjątku, użytkownik zobaczy okno z informacją, że aplikacja przestała działać.
W niektórych przypadkach system zgłasza wyjątek wewnętrzny. W takich przypadkach możesz sprawdzić, jaki wyjątek wystąpił, przeglądając zrzut stosu, a szczegółowe informacje o błędzie znajdziesz w Logcat.
Wyjątek wewnętrzny: przekroczono limit czasu
System nakłada limit czasu, przez jaki usługi na pierwszym planie synchronizujące dane i przetwarzające multimedia mogą działać, gdy aplikacja jest w tle. Jeśli usługa przekroczy ten limit, system wywoła metodę Service.onTimeout(int,int)
usługi. Usługa ma kilka sekund na zadzwonienie pod numer stopSelf()
. Jeśli usługa nie zatrzyma się sama, system wygeneruje wewnętrzny RemoteServiceException
, który spowoduje awarię aplikacji.
Diagnozowanie:
Informacje o wyjątku znajdziesz w zrzucie stosu, a szczegółowe informacje o błędzie znajdziesz w Logcat. W takim przypadku Logcat wyświetli ten komunikat o błędzie:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"
Rozwiązanie:
Upewnij się, że wszystkie usługi na pierwszym planie z ograniczeniem czasowym kończą pracę i wywołują stopForeground(int)
w ramach limitu czasu systemowego.
Usługi działające na pierwszym planie muszą implementować interfejs Service.onTimeout(int,int)
.
Upewnij się, że implementacja tej metody od razu wywołuje funkcję stopSelf()
.
Wyjątek wewnętrzny: ForegroundServiceDidNotStartInTimeException
Gdy uruchomisz usługę, wywołując context.startForegroundService()
, ma ona kilka sekund na przekształcenie się w usługę działającą na pierwszym planie przez wywołanie ServiceCompat.startForeground()
.
Jeśli usługa tego nie zrobi, zgłosi wewnętrzny błąd ForegroundServiceDidNotStartInTimeException
.
Diagnozowanie:
Informacje o wyjątku znajdziesz w zrzucie stosu, a szczegółowe informacje o błędzie znajdziesz w Logcat. W takim przypadku Logcat wyświetli ten komunikat o błędzie:
android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()
Rozwiązanie:
Upewnij się, że wszystkie nowo utworzone usługi na pierwszym planie wywołują ServiceCompat.startForeground()
w ciągu kilku sekund.
ForegroundServiceStartNotAllowedException
Błąd:
System zgłasza błąd ForegroundServiceStartNotAllowedException
.
Przyczyna:
Zwykle jest to spowodowane uruchomieniem przez aplikację usługi działającej na pierwszym planie w tle, gdy nie ma ważnego wyjątku.
Od Androida 12 (poziom interfejsu API 31) aplikacje nie mogą uruchamiać usług działających na pierwszym planie, gdy działają w tle, z kilkoma wyjątkami.
Jeśli spróbujesz uruchomić usługę na pierwszym planie w tle i nie spełniasz wymagań jednego z wyjątków, system zgłosi błąd ForegroundServiceStartNotAllowedException
. System robi to również wtedy, gdy nie spełniasz wymagań dotyczących zwolnienia.
Na przykład aplikacja może mieć przycisk, który użytkownik może kliknąć. Spowoduje to, że aplikacja wykona pewne przetwarzanie, a następnie uruchomi usługę na pierwszym planie. W takim przypadku istnieje ryzyko, że użytkownik kliknie przycisk, a następnie natychmiast przełączy aplikację w tryb tła. Aplikacja spróbuje wtedy uruchomić usługę w tle. Jeśli aplikacja nie spełnia jednego z określonych wyjątków, system zgłasza błąd ForegroundServiceStartNotAllowedException
.
Niektóre wyjątki mają też krótki termin ważności. Na przykład istnieje krótkie zwolnienie, jeśli aplikacja uruchamia usługę działającą na pierwszym planie w odpowiedzi na wiadomość FCM o wysokim priorytecie. Jeśli nie uruchomisz usługi wystarczająco szybko, otrzymasz ForegroundServiceStartNotAllowedException
.
W przypadku nowych wersji Androida niektóre konkretne wyjątki mogą stać się bardziej restrykcyjne. Jeśli zmienisz wersję Androida, na którą jest kierowana Twoja aplikacja, zapoznaj się z dokumentacją dotyczącą zmian w usługach działających na pierwszym planie i upewnij się, że Twoja aplikacja nadal spełnia jeden z dozwolonych wyjątków.
Rozwiązanie:
Zmień sposób działania aplikacji, aby nie musiała uruchamiać usług na pierwszym planie, gdy działa w tle, lub potwierdź, że Twoja aplikacja spełnia jeden z warunków zwolnienia.
Możesz używać komponentów uwzględniających cykl życia, aby zarządzać cyklem życia aplikacji i uniknąć przypadkowego uruchomienia usługi działającej na pierwszym planie w tle.
SecurityException
Błąd:
System zgłaszaSecurityException
.
Przyczyna:
Aplikacja próbowała uruchomić usługę na pierwszym planie bez wymaganych uprawnień.
- Jeśli aplikacja jest kierowana na Androida 9 (API na poziomie 28) lub nowszego, musi mieć uprawnienie
FOREGROUND_SERVICE
do uruchamiania usługi działającej na pierwszym planie. - Jeśli aplikacja jest kierowana na Androida 14 (API na poziomie 34) lub nowszego, musi spełniać wszystkie wymagania wstępne dotyczące jej typu usługi działającej na pierwszym planie. Te wymagania wstępne są szczegółowo opisane w dokumentacji typów usług na pierwszym planie. Zwróć szczególną uwagę na te wymagania:
- Niektóre typy usług na pierwszym planie wymagają określonych uprawnień w czasie działania. Na przykład usługa działająca na pierwszym planie do zdalnego przesyłania wiadomości musi mieć uprawnienie
FOREGROUND_SERVICE_REMOTE_MESSAGING
.
- Niektóre typy usług na pierwszym planie wymagają określonych uprawnień w czasie działania. Na przykład usługa działająca na pierwszym planie do zdalnego przesyłania wiadomości musi mieć uprawnienie
- W kilku przypadkach istnieją dodatkowe ograniczenia dotyczące uprawnień wymaganych przez niektóre typy usług na pierwszym planie, które obowiązują podczas korzystania z aplikacji. Te uprawnienia są przyznawane aplikacji tylko wtedy, gdy jest ona na pierwszym planie (z kilkoma wyjątkami). Oznacza to, że nawet jeśli aplikacja poprosiła o jedno z tych uprawnień i je otrzymała, a następnie spróbuje uruchomić usługę na pierwszym planie, gdy będzie działać w tle, system zgłosi błąd
SecurityException
, nawet jeśli aplikacja ma wyjątek umożliwiający uruchomienie usługi na pierwszym planie z poziomu tła. Więcej informacji znajdziesz w artykule Ograniczenia dotyczące uruchamiania usług na pierwszym planie, które wymagają uprawnień podczas używania.- Możesz otrzymać
SecurityException
, jeśli poprosisz o niezbędne uprawnienia, ale uruchomisz usługę na pierwszym planie, zanim potwierdzisz, że wymagane uprawnienia zostały przyznane.
- Możesz otrzymać
Rozwiązanie:
Zanim uruchomisz usługę działającą na pierwszym planie, poproś o wszystkie odpowiednie uprawnienia dotyczące takiej usługi i upewnij się, że spełniasz wszystkie inne wymagania wstępne dotyczące czasu działania.