Systemeinschränkungen für Hintergrundarbeit

Hintergrundprozesse können speicher- und energieintensiv sein. Beispiel: kann der implizite Broadcast viele Hintergrundprozesse starten, hören Sie darauf zu, auch wenn diese Prozesse nicht viel Arbeit leisten. Dies kann eine erheblichen Einfluss auf die Geräteleistung und die Nutzererfahrung.

Um Systemeinschränkungen zu vermeiden, achten Sie darauf, dass Sie die richtige API für Ihr Hintergrundaufgabe. Die In der Dokumentation Hintergrundaufgaben finden Sie Informationen zur Auswahl. die richtige API für Ihre Anforderungen.

Vom Nutzer initiierte Einschränkungen

Wenn eine App einige der in Android Vitals beschriebenen Probleme aufweist, wird der Nutzer vom System aufgefordert, den Zugriff der App auf Systemressourcen zu beschränken.

Wenn das System feststellt, dass eine App übermäßig viele Ressourcen beansprucht, und die Möglichkeit, die Aktionen der App einzuschränken. Folgende Verhaltensweisen können die Benachrichtigung auslösen:

  1. Übermäßige Wakelocks: 1 Teil-Wakelock, der bei ausgeschaltetem Display eine Stunde lang gehalten wird. Aus
  2. Übermäßige Hintergrunddienste: wenn die App auf API-Levels unter 26 ausgerichtet ist und bietet übermäßig viele Hintergrunddienste.

Die genauen Einschränkungen werden vom Gerätehersteller festgelegt. Für In AOSP-Builds können eingeschränkte Apps z. B. keine Jobs ausführen, keine Alarme auslösen oder Netzwerk, es sei denn, die App wird im Vordergrund ausgeführt.

Einschränkungen für den Empfang von Netzwerkaktivitäts-Broadcasts

Apps empfangen keine CONNECTIVITY_ACTION-Broadcasts, wenn sie sich hier registrieren: erhalten sie in ihrem Manifest und Prozesse, die von der Übertragung abhängen. wird nicht gestartet. Das könnte zu einem Problem für Apps führen, die auf Netzwerkdaten achten möchten Änderungen vornehmen oder Bulk-Netzwerkaktivitäten durchführen, wenn das Gerät eine Verbindung zu einem kostenlos verfügbar sind. Es gibt bereits mehrere Lösungen zur Umgehung dieser Einschränkung gibt es im Android-Framework, aber die Wahl der richtigen Lösung hängt davon ab, was Ihre App erreichen soll.

Arbeiten für nicht getaktete Verbindungen planen

Füge beim Erstellen einer WorkRequest einen NetworkType.UNMETERED-Constraint hinzu.

fun scheduleWork(context: Context) {
    val workManager = WorkManager.getInstance(context)
    val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
       .setConstraints(
           Constraints.Builder()
               .setRequiredNetworkType(NetworkType.UNMETERED)
               .build()
           )
       .build()

    workManager.enqueue(workRequest)
}

Wenn die Bedingungen für Ihre Arbeit erfüllt sind, erhält Ihre App einen Rückruf, um sie auszuführen. Die Methode doWork() in der angegebenen Worker-Klasse.

Netzwerkkonnektivität überwachen, während die App ausgeführt wird

Aktive Apps können immer noch auf CONNECTIVITY_CHANGE mit einem registriert BroadcastReceiver. Die ConnectivityManager API bietet eine robustere Methode, um einen Rückruf nur dann anzufordern, wenn das Netzwerk erfüllt sind.

NetworkRequest-Objekte definieren die Parameter des Netzwerk-Callbacks in Nutzungsbedingungen von NetworkCapabilities. Sie erstellen NetworkRequest Objekte mit der Klasse NetworkRequest.Builder. registerNetworkCallback übergibt dann das NetworkRequest-Objekt an das System. Wenn das Netzwerk erfüllt sind, empfängt die App einen Callback, mit dem die Methode onAvailable() definiert in eigenen Kurs ConnectivityManager.NetworkCallback.

Die App erhält weiterhin Rückrufe, bis sie entweder beendet oder aufgerufen wird. unregisterNetworkCallback() abrufen.

Einschränkungen für den Empfang von Bild- und Videoübertragungen

Apps können keine ACTION_NEW_PICTURE oder ACTION_NEW_VIDEO Übertragungen Diese Einschränkung hilft, die Leistung und Nutzererfahrung beeinflusst, wenn mehrere Apps aktiviert werden müssen, Bilder oder Videos zu verarbeiten.

Herausfinden, welche Inhaltsstellen eine Arbeit ausgelöst haben

Mit WorkerParameters kann Ihre App nützliche Informationen darüber erhalten, Inhaltsbehörden und URIs haben die Arbeit ausgelöst:

List<Uri> getTriggeredContentUris()

Gibt eine Liste der URIs zurück, die die Arbeit ausgelöst haben. Dieses Feld ist leer, wenn Entweder haben keine URIs die Arbeit ausgelöst (z. B. aufgrund eines einer Frist oder aus einem anderen Grund) oder die Anzahl der geänderten URIs größer als 50.

List<String> getTriggeredContentAuthorities()

Gibt eine Stringliste mit Inhaltsbehörden zurück, die das Werk ausgelöst haben. Wenn Die zurückgegebene Liste ist nicht leer. Verwenden Sie getTriggeredContentUris() zum Abrufen. die Details der geänderten URIs.

Der folgende Beispielcode überschreibt die Methode CoroutineWorker.doWork() und zeichnet die Inhaltsbehörden und URIs auf, die den Job ausgelöst haben:

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()
    }
}

App mit Systemeinschränkungen testen

Apps für die Ausführung auf Geräten mit geringem Arbeitsspeicher oder bei unzureichendem Arbeitsspeicher optimieren Leistung und Nutzererfahrung verbessern. Abhängigkeiten aus dem Hintergrund entfernen und von Manifesten registrierte implizite Übertragungsempfänger in deiner App unterstützen auf solchen Geräten besser funktioniert. Es wird empfohlen, Ihre App für ohne diese Hintergrundprozesse gänzlich zu verwenden.

Mit einigen zusätzlichen Android Debug Bridge (ADB)-Befehlen können Sie Ihre App testen. wenn diese Hintergrundprozesse deaktiviert sind:

  • Um Bedingungen zu simulieren, in denen implizite Broadcasts und Hintergrunddienste nicht verfügbar ist, geben Sie den folgenden Befehl ein:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore

  • Geben Sie Folgendes ein, um implizite Broadcasts und Hintergrunddienste wieder zu aktivieren Befehl:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow

App weiter optimieren

Weitere Möglichkeiten zur Optimierung Ihrer Hintergrundaufgaben finden Sie finden Sie unter den Artikel Akkuverbrauch für Aufgabenplanungs-APIs optimieren Dokumentation.