Procesy działające w tle mogą zużywać dużo pamięci i baterii. Na przykład komunikat ogólny może uruchomić wiele procesów w tle, które zarejestrowały się, aby go nasłuchiwać, nawet jeśli te procesy nie wykonują zbyt wielu zadań. Może to mieć znaczący wpływ na wydajność urządzenia i wygodę użytkownika.
Aby uniknąć ograniczeń systemowych, używaj odpowiedniego interfejsu API do zadań działających w tle. Dokumentacja Przegląd zadań działających w tle pomoże Ci wybrać odpowiedni interfejs API.
Ograniczenia inicjowane przez użytkownika
Jeśli aplikacja wykazuje niektóre z niepożądanych zachowań opisanych w Android vitals, system wyświetla użytkownikowi prośbę o ograniczenie dostępu tej aplikacji do zasobów systemowych.
Jeśli system zauważy, że aplikacja zużywa nadmierną ilość zasobów, powiadamia o tym użytkownika i daje mu możliwość ograniczenia działań aplikacji. Zachowania, które mogą spowodować wyświetlenie powiadomienia:
- Nadmierna liczba blokad uśpienia: 1 częściowa blokada uśpienia utrzymywana przez godzinę, gdy ekran jest wyłączony.
- Nadmierna liczba usług działających w tle: jeśli aplikacja jest przeznaczona na poziomy interfejsu API niższe niż 26 i ma nadmierną liczbę usług działających w tle.
Dokładne ograniczenia są określane przez producenta urządzenia. Na przykład w przypadku kompilacji AOSP aplikacje z ograniczeniami nie mogą uruchamiać zadań, wywoływać alarmów ani korzystać z sieci, z wyjątkiem sytuacji, gdy aplikacja jest na pierwszym planie.
Ograniczenia dotyczące odbierania transmisji aktywności sieciowej
Aplikacje nie otrzymują CONNECTIVITY_ACTION transmisji, jeśli zarejestrują się, aby
je odbierać w swoim manifeście, a procesy, które zależą od tej transmisji,
nie zostaną uruchomione. Może to stanowić problem dla aplikacji, które chcą nasłuchiwać zmian w sieci lub wykonywać zbiorcze działania sieciowe, gdy urządzenie łączy się z siecią bez limitu danych. W platformie Android istnieje już kilka rozwiązań pozwalających obejść to ograniczenie, ale wybór odpowiedniego zależy od tego, co chcesz osiągnąć w aplikacji.
Planowanie pracy w przypadku połączeń bez limitu danych
Podczas tworzenia WorkRequest dodaj Constraint NetworkType.UNMETERED.
fun scheduleWork(context: Context) {
val workManager = WorkManager.getInstance(context)
val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
)
.build()
workManager.enqueue(workRequest)
}
Gdy warunki pracy zostaną spełnione, aplikacja otrzyma wywołanie zwrotne, aby uruchomić
metodę doWork() w określonej klasie Worker.
Monitorowanie łączności sieciowej podczas działania aplikacji
Uruchomione aplikacje mogą nadal nasłuchiwać CONNECTIVITY_CHANGE za pomocą zarejestrowanego elementu BroadcastReceiver. Jednak interfejs API ConnectivityManager
zapewnia bardziej niezawodną metodę żądania wywołania zwrotnego tylko wtedy, gdy zostaną spełnione określone warunki sieciowe.
NetworkRequest obiekty określają parametry wywołania zwrotnego sieci w
postaci NetworkCapabilities. Obiekty NetworkRequest tworzysz
za pomocą klasy NetworkRequest.Builder. registerNetworkCallback
następnie przekazuje obiekt NetworkRequest do systemu. Gdy warunki sieciowe
zostaną spełnione, aplikacja otrzyma wywołanie zwrotne, aby wykonać metodę
onAvailable() zdefiniowaną w klasie
ConnectivityManager.NetworkCallback.
Aplikacja będzie nadal otrzymywać wywołania zwrotne, dopóki nie zostanie zamknięta lub nie wywoła metody unregisterNetworkCallback().
Ograniczenia dotyczące odbierania transmisji obrazów i filmów
Aplikacje nie mogą wysyłać ani odbierać transmisji ACTION_NEW_PICTURE ani ACTION_NEW_VIDEO. To ograniczenie pomaga zmniejszyć wpływ na wydajność i wygodę użytkownika, gdy kilka aplikacji musi się uruchomić, aby przetworzyć nowy obraz lub film.
Określanie, które organy treści wywołały pracę
WorkerParameters umożliwia aplikacji otrzymywanie przydatnych informacji o tym, które organy treści i identyfikatory URI wywołały pracę:
List<Uri> getTriggeredContentUris()
Zwraca listę identyfikatorów URI, które wywołały pracę. Jest ona pusta, jeśli praca nie została wywołana przez żaden identyfikator URI (np. praca została wywołana z powodu terminu lub z innego powodu) albo liczba zmienionych identyfikatorów URI jest większa niż 50.
List<String> getTriggeredContentAuthorities()
Zwraca listę ciągów znaków zawierającą organy treści, które wywołały pracę. Jeśli zwrócona lista nie jest pusta, użyj getTriggeredContentUris(), aby pobrać szczegóły dotyczące tego, które identyfikatory URI uległy zmianie.
Poniższy przykładowy kod zastępuje metodę CoroutineWorker.doWork()
i rejestruje organy treści oraz identyfikatory URI, które wywołały zadanie:
class MyWorker(
appContext: Context,
params: WorkerParameters
): CoroutineWorker(appContext, params)
override suspend fun doWork(): Result {
StringBuilder().apply {
append("Media content has changed:\n")
params.triggeredContentAuthorities
.takeIf { it.isNotEmpty() }
?.let { authorities ->
append("Authorities: ${authorities.joinToString(", ")}\n")
append(params.triggeredContentUris.joinToString("\n"))
} ?: append("(No content)")
Log.i(TAG, toString())
}
return Result.success()
}
}
Testowanie aplikacji pod kątem ograniczeń systemowych
Optymalizacja aplikacji pod kątem działania na urządzeniach z małą ilością pamięci lub w warunkach małej ilości pamięci może poprawić wydajność i wygodę użytkownika. Usunięcie zależności od usług w tle i komunikatów ogólnych zarejestrowanych w pliku manifestu może pomóc aplikacji w lepszym działaniu na takich urządzeniach. Zalecamy zoptymalizowanie aplikacji pod kątem działania bez użycia tych procesów działających w tle.
Niektóre dodatkowe polecenia Android Debug Bridge (ADB) mogą pomóc w testowaniu zachowania aplikacji przy wyłączonych procesach działających w tle:
Aby zasymulować warunki, w których niedostępne są niejawne transmisje i usługi działające w tle, wpisz to polecenie:
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignoreAby ponownie włączyć niejawne transmisje i usługi działające w tle, wpisz to polecenie:
$ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow
Dalsza optymalizacja aplikacji
Więcej informacji o optymalizacji zachowania zadań działających w tle znajdziesz w dokumentacji Optymalizacja wykorzystania baterii w przypadku interfejsów API do planowania zadań.