Na tej stronie znajdziesz informacje o najczęstszych przyczynach awarii usług na pierwszym planie oraz wskazówki, które pomogą Ci zidentyfikować problem.
W tym dokumencie omawiamy te zagadnienia:
Zanim zaczniesz rozwiązywać problem
Sprawdź, czy nie nastąpiły ostatnie zmiany usług na pierwszym planie.
Nieprawidłowe korzystanie z usług na pierwszym planie może mieć negatywny wpływ na wydajność urządzenia i żywotność baterii. Z tego powodu wersje platformy Android często wprowadzają zmiany w zachowaniu usług na pierwszym planie, aby ograniczyć te negatywne skutki.
Jeśli masz problemy z usługami na pierwszym planie, sprawdź dokumentację z informacjami o zmianach w usługach na pierwszym planie, aby sprawdzić, czy nie pojawiły się w niej jakieś zmiany, które mogłyby wyjaśnić problem. Szczególnie ważne jest sprawdzenie zmian w tych przypadkach:
- Kod usługi na pierwszym planie, który wcześniej działał, teraz zawodzi
- właśnie rozpoczęto testowanie na nowej wersji platformy lub zmieniono poziom interfejsu API, na który kierowana jest aplikacja;
Jeśli testujesz urządzenie na wersji przedpremierowej platformy dla deweloperów, sprawdź najnowszą wersję dokumentacji dla deweloperó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 zatrzyma usługę i wygeneruje 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 korzystają z typu krótka usługa, muszą się szybko kończyć, czyli w ciągu około 3 minut. Po upływie tego czasu system wywołuje metodę Service.onTimeout(int,int)
usługi. Usługa ma kilka sekund na wywołanie stopSelf()
. Jeśli usługa nie zatrzyma się sama, system spowoduje wyświetlenie błędu Aplikacja nie odpowiada.
Diagnoza:
Jeśli ANR został spowodowany przez usługę na pierwszym planie, która nie zatrzymała się sama, system zgłasza wewnętrzny wyjątek. Aby sprawdzić, czy to był problem, użyj narzędzia Logcat. W takim przypadku w logu pojawia 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 ograniczonym czasem działania kończą pracę i wywołują funkcję stopForeground(int)
w ramach limitu czasu systemu.
Upewnij się, że usługi na pierwszym planie implementują 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 opisano kilka problemów z usługami na pierwszym planie, które mogą powodować wyjątek w systemie. Jeśli aplikacja nie zarejestruje wyjątku, użytkownik zobaczy okno z informacją, że aplikacja została zamknięta.
W niektórych przypadkach system zgłasza wewnętrzny wyjątek. Nie możesz ich przechwycić, ale możesz sprawdzić w Logcat, jakie wyjątki zostały wygenerowane.
Wyjątek wewnętrzny: przekroczony limit czasu
System nakłada limit czasu, przez jaki usługi na pierwszym planie mogą wykonywać zadania związane z synchronizacją danych i przetwarzaniem multimediów, gdy aplikacja działa w tle. Jeśli usługa przekroczy ten limit, system wywoła metodę Service.onTimeout(int,int)
tej usługi. Usługa ma kilka sekund na wywołanie
stopSelf()
. Jeśli usługa nie zatrzyma się sama, system wygeneruje wewnętrzny wyjątek, który spowoduje awarię aplikacji.
Diagnoza:
Jeśli przyczyną jest przekroczenie limitu czasu, w Logcat pojawi się komunikat:
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 ograniczonym czasem działania kończą pracę i wywołują funkcję stopForeground(int)
w ramach limitu czasu systemu.
Upewnij się, że usługi na pierwszym planie implementują Service.onTimeout(int,int)
.
Upewnij się, że implementacja tej metody od razu wywołuje funkcję stopSelf()
.
Wyjątek wewnętrzny: ForegroundServiceDidNotStartInTimeException
Gdy uruchamiasz usługę przez wywołanie
context.startForegroundService()
,
ta usługa ma kilka sekund na przekształcenie się w usługę na pierwszym planie przez wywołanie
ServiceCompat.startForeground()
.
Jeśli usługa tego nie zrobi, system spowoduje błąd ANR.
Diagnoza:
Jeśli usługa na pierwszym planie nie zostanie uruchomiona na czas, aplikacja ulegnie awarii, a użytkownik zobaczy okno Aplikacja została zatrzymana. W takim przypadku w Logcat znajdziesz ten komunikat:
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ą funkcję ServiceCompat.startForeground()
w ciągu kilku sekund.
ForegroundServiceStartNotAllowedException
Błąd:
System zwraca ForegroundServiceStartNotAllowedException
.
Przyczyna:
Przyczyną tej sytuacji jest zwykle uruchomienie przez aplikację usługi na pierwszym planie w tle, gdy nie ma ważnego wyłączenia.
Począwszy od Androida 12 (poziom interfejsu API 31) aplikacje nie mogą uruchamiać usług na pierwszym planie, gdy aplikacja działa w tle. Wyjątkiem są niektóre konkretne wyjątki.
Jeśli spróbujesz uruchomić usługę na pierwszym planie w tle, a nie spełniasz wymagań żadnej z wyjątków, system zgłosi błąd ForegroundServiceStartNotAllowedException
. System robi to również wtedy, gdy nie spełniasz wymagań dotyczących wyjątku.
Aplikacja może na przykład mieć przycisk, który użytkownik może kliknąć, co spowoduje przetworzenie danych i uruchomienie usługi na pierwszym planie. W takim przypadku istnieje ryzyko, że użytkownik kliknie przycisk, a następnie natychmiast przeniesie aplikację na drugi plan. W takim przypadku aplikacja spróbuje uruchomić usługę w tle. Jeśli aplikacja nie spełnia jednego z wyjątków, system ForegroundServiceStartNotAllowedException
.
Dodatkowo niektóre wyjątki mają krótki termin ważności. Na przykład, jeśli aplikacja uruchomi usługę na pierwszym planie w odpowiedzi na wiadomość FCM o wysokim priorytecie, będzie to krótkotrwałe odstępstwo od zasady. Jeśli nie uruchomisz usługi wystarczająco szybko, otrzymasz ForegroundServiceStartNotAllowedException
.
Niektóre wyjątki stają się bardziej restrykcyjne w raz z wydaniem nowej wersji Androida. Jeśli zmienisz wersję Androida, na którą kierujesz swoją aplikację, zapoznaj się z dokumentacją dotyczącą zmian w usługach na pierwszym planie i sprawdź, czy Twoja aplikacja nadal spełnia kryteria jednej z dozwolonych wyjątków.
Rozwiązanie:
Zmień przepływ pracy w aplikacji, aby nie musiała uruchamiać usług na pierwszym planie, gdy działa w tle, lub sprawdź, czy aplikacja spełnia jeden z wyjątków.
Aby zarządzać cyklem życia aplikacji i uniknąć przypadkowego uruchamiania usługi na pierwszym planie z tła, możesz używać składników cyklu życia, takich jak LiveData
.
SecurityException
Błąd:
System zwracaSecurityException
.
Przyczyna:
Twoja aplikacja próbowała uruchomić usługę na pierwszym planie bez odpowiednich uprawnień.
- Jeśli aplikacja jest kierowana na Androida 9 (API na poziomie 28) lub nowszego, musi mieć uprawnienie
FOREGROUND_SERVICE
, aby uruchamiać usługę na pierwszym planie. - Jeśli aplikacja jest kierowana na Androida 14 (API na poziomie 34) lub nowszego, musi spełniać wszystkie wymagania wstępne dla typu usługi na pierwszym planie. Wymagania wstępne są opisane w dokumentacji dotyczącej 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 wykonywania. Na przykład usługa na pierwszym planie obsługująca wiadomości zdalne musi mieć uprawnienie
FOREGROUND_SERVICE_REMOTE_MESSAGING
.
- Niektóre typy usług na pierwszym planie wymagają określonych uprawnień w czasie wykonywania. Na przykład usługa na pierwszym planie obsługująca wiadomości zdalne musi mieć uprawnienie
- W niektórych przypadkach obowiązują dodatkowe ograniczenia dotyczące uprawnień potrzebnych niektórym typom usług działających na pierwszym planie. Te uprawnienia są przyznawane aplikacji tylko wtedy, gdy jest ona na pierwszym planie (z niektórymi wyjątkami). Oznacza to, że nawet jeśli aplikacja poprosi o jeden z tych uprawnień i je otrzyma, to jeśli spróbuje uruchomić usługę na pierwszym planie, gdy sama działa w tle, system zgłosi błąd
SecurityException
, nawet jeśli aplikacja ma wyjątek umożliwiający uruchamianie usługi na pierwszym planie z tła. Więcej informacji znajdziesz w artykule Ograniczenia dotyczące uruchamiania usług na pierwszym planie, które wymagają uprawnień podczas korzystania.- Możesz otrzymać błąd
SecurityException
, jeśli poprosisz o wymagane uprawnienia, ale uruchomisz usługę na pierwszym planie, zanim potwierdzisz, że te uprawnienia zostały przyznane.
- Możesz otrzymać błąd
Rozwiązanie:
Zanim uruchomisz usługę na pierwszym planie, poproś o wszystkie odpowiednie uprawnienia i sprawdź, czy spełniasz wszystkie inne wymagania wstępne.