ANRs

Wenn der UI-Thread einer Android-App zu lange blockiert ist, wird der ANR-Fehler „App antwortet nicht“ ausgelöst. Wenn die App im Vordergrund ausgeführt wird, zeigt das System dem Nutzer ein Dialogfeld an (siehe Abbildung 1). Über das ANR-Dialogfeld kann der Nutzer das Beenden der App erzwingen.

Abbildung 1. ANR-Dialogfeld, das dem Nutzer angezeigt wird

Abbildung 1: ANR-Dialogfeld, das dem Nutzer angezeigt wird

ANR-Fehler stellen ein Problem dar, da der Hauptthread der Anwendung, der für die Aktualisierung der Benutzeroberfläche verantwortlich ist, keine Nutzereingabeereignisse verarbeiten oder zeichnen kann, was den Nutzer frustriert. Weitere Informationen zum Hauptthread der Anwendung finden Sie unter Prozesse und Threads.

Ein ANR-Fehler wird für Ihre App ausgelöst, wenn eine der folgenden Bedingungen eintritt:

  • Zeitüberschreitung bei der Eingabeweiterleitung:Wenn Ihre App nicht innerhalb von 5 Sekunden auf ein Eingabeereignis (z. B. Tastendruck oder Bildschirmberührung) reagiert hat.
  • Dienstausführung:Wenn ein von Ihrer Anwendung deklarierter Dienst die Ausführung von Service.onCreate() und Service.onStartCommand()/Service.onBind() nicht innerhalb weniger Sekunden beenden kann.
  • Service.startForeground() nicht aufgerufen:Wenn Ihre App Context.startForegroundService() verwendet, um einen neuen Dienst im Vordergrund zu starten, der Dienst dann aber startForeground() nicht innerhalb von 5 Sekunden aufruft.
  • Broadcast of Intent:Wenn eine BroadcastReceiver nicht innerhalb eines festgelegten Zeitraums ausgeführt wurde. Wenn die App Aktivitäten im Vordergrund ausführt, beträgt die Zeitüberschreitung 5 Sekunden.
  • JobScheduler-Interaktionen:Wenn ein JobService nicht innerhalb weniger Sekunden von JobService.onStartJob() oder JobService.onStopJob() zurückgegeben wird oder wenn ein vom Nutzer initiierter Job gestartet wird und Ihre Anwendung JobService.setNotification() nicht innerhalb weniger Sekunden nach dem Aufruf von JobService.onStartJob() aufruft. Bei Apps, die auf Android 13 und niedriger ausgerichtet sind, sind die ANR-Fehler lautlos und werden nicht an die App gemeldet. Bei Apps, die auf Android 14 und höher ausgerichtet sind, sind die ANR-Fehler explizit und werden der App gemeldet.

Wenn bei Ihrer App ANR-Fehler auftreten, können Sie der Anleitung in diesem Artikel folgen, um das Problem zu diagnostizieren und zu beheben.

Problem erkennen

Wenn Sie Ihre App bereits veröffentlicht haben, können Sie mit Android Vitals Informationen zu ANR-Fehlern für Ihre App abrufen. Sie können auch andere Tools verwenden, um ANR-Fehler vor Ort zu erkennen. Beachten Sie jedoch, dass Drittanbietertools im Gegensatz zu Android Vitals keine ANR-Fehler für ältere Android-Versionen (Android 10 und niedriger) melden können.

Android Vitals

Mit Android Vitals kannst du die ANR-Rate deiner App beobachten und verbessern. In Android Vitals werden mehrere ANR-Raten gemessen:

  • ANR-Rate:Der Prozentsatz der aktiven Nutzer pro Tag, bei denen eine Art von ANR-Fehler aufgetreten ist.
  • Vom Nutzer wahrgenommene ANR-Rate:Prozentsatz der aktiven Nutzer pro Tag, bei denen mindestens ein vom Nutzer wahrgenommener ANR-Fehler aufgetreten ist. Derzeit werden nur ANRs vom Typ Input dispatching timed out als vom Nutzer wahrgenommen betrachtet.
  • Mehrfach-ANR-Rate:Prozentsatz der aktiven Nutzer pro Tag, bei denen mindestens zwei ANR-Fehler aufgetreten sind.

Ein täglich aktiver Nutzer ist ein einzelner Nutzer, der Ihre App an einem Tag auf einem einzelnen Gerät und möglicherweise über mehrere Sitzungen hinweg verwendet. Wenn ein Nutzer Ihre App an einem Tag auf mehr als einem Gerät verwendet, wird jedes Gerät zur Anzahl der aktiven Nutzer für diesen Tag addiert. Wenn mehrere Nutzer an einem Tag dasselbe Gerät verwenden, wird dies als ein aktiver Nutzer gezählt.

Die vom Nutzer wahrgenommene ANR-Rate ist ein Vitalparameter, d. h., er beeinflusst die Sichtbarkeit Ihrer App bei Google Play. Das ist wichtig, da die gezählten ANR-Fehler immer auftreten, wenn der Nutzer mit der Anwendung interagiert, und daher die größte Störung verursachen.

Google Play hat für diesen Messwert zwei Grenzwerte zu unerwünschtem Verhalten festgelegt:

  • Grenzwert zu unerwünschtem Verhalten:Bei mindestens 0, 47% der aktiven Nutzer pro Tag tritt auf allen Gerätemodellen ein vom Nutzer wahrgenommener ANR-Fehler auf.
  • Grenzwert zu unerwünschtem Verhalten auf einzelnen Geräten:Bei mindestens 8% der Nutzer pro Tag tritt bei einem einzelnen Gerätemodell ein vom Nutzer wahrgenommener ANR-Fehler auf.

Wenn deine App den allgemeinen Grenzwert zu unerwünschtem Verhalten überschreitet, ist sie wahrscheinlich auf allen Geräten weniger gut sichtbar. Wenn deine App auf einigen Geräten den Grenzwert zu unerwünschtem Verhalten pro Gerät überschreitet, ist sie auf diesen Geräten wahrscheinlich weniger gut sichtbar und in deinem Store-Eintrag wird möglicherweise eine Warnung angezeigt.

Android Vitals kann dich über die Play Console benachrichtigen, wenn deine App übermäßige ANR-Fehler aufweist.

Informationen dazu, wie Google Play Android Vitals-Daten erhebt, findest du in der Play Console-Dokumentation.

ANR-Fehler diagnostizieren

Es gibt einige gängige Muster, nach denen du bei der Diagnose von ANR-Fehlern Ausschau halten solltest:

  • Die App führt langsame Vorgänge mit E/A im Hauptthread aus.
  • Die App führt eine lange Berechnung im Hauptthread durch.
  • Der Hauptthread führt einen synchronen Binderaufruf an einen anderen Prozess durch, und die Rückgabe dieses anderen Prozesses dauert sehr lange.
  • Der Hauptthread wird blockiert, wenn er für einen langen Vorgang, der in einem anderen Thread ausgeführt wird, auf einen synchronisierten Block wartet.
  • Der Hauptthread befindet sich in einem Deadlock mit einem anderen Thread, entweder in Ihrem Prozess oder über einen Binderaufruf. Der Hauptthread wartet nicht nur auf den Abschluss eines langen Vorgangs, sondern befindet sich in einer Deadlock-Situation. Weitere Informationen finden Sie unter Deadlock auf Wikipedia.

Die folgenden Methoden können dir helfen, die Ursache deiner ANR-Fehler zu bestimmen.

Gesundheitsstatistiken

HealthStats stellt Messwerte zum Zustand einer Anwendung bereit, indem die Gesamtnutzer- und Systemzeit, die CPU-Zeit, das Netzwerk, die Radiostatistiken, die Ein-/Aus-Zeit für den Bildschirm und die Weckzeit erfasst werden. Dies kann beim Messen der gesamten CPU-Auslastung und der Entladung des Akkus helfen.

Fehler beheben

Mit Debug können Android-Apps während der Entwicklung geprüft werden. Dazu gehören Tracing und Anzahl der Zuweisungszahlen, um Verzögerungen und Verzögerungen in den Apps zu erkennen. Sie können auch Debug verwenden, um Zähler für Laufzeit und nativer Arbeitsspeicher sowie Arbeitsspeichermesswerte abzurufen, mit denen Sie den Arbeitsspeicherbedarf eines bestimmten Prozesses ermitteln können.

Informationen zum Anwendungs-Exit

ApplicationExitInfo ist ab Android 11 (API-Level 30) verfügbar und liefert Informationen zum Grund für das Beenden der App. Dazu gehören ANR-Fehler, geringer Arbeitsspeicher, App-Abstürze, eine übermäßige CPU-Auslastung, Nutzerunterbrechungen, Systemunterbrechungen und Änderungen der Laufzeitberechtigungen.

Strenger Modus

Mit StrictMode können Sie beim Entwickeln Ihrer Anwendung versehentliche E/A-Vorgänge im Hauptthread finden. Sie können StrictMode auf Anwendungs- oder Aktivitätsebene verwenden.

Dialogfelder für ANR-Fehler im Hintergrund aktivieren

Android zeigt nur dann ANR-Dialogfelder für Apps an, deren Verarbeitung der Broadcast-Nachricht zu lange dauert, wenn die Option Alle ANR-Fehler anzeigen in den Entwickleroptionen des Geräts aktiviert ist. Aus diesem Grund werden dem Nutzer nicht immer ANR-Dialogfelder im Hintergrund angezeigt, bei der App können jedoch weiterhin Leistungsprobleme auftreten.

TraceView

Mit Traceview können Sie ein Trace Ihrer laufenden Anwendung abrufen, während Sie die Anwendungsfälle durchgehen und die Stellen ermitteln, an denen der Hauptthread ausgelastet ist. Informationen zur Verwendung von Traceview finden Sie unter Profilerstellung mit Traceview und dmtracedump.

Traces-Datei abrufen

Android speichert Trace-Informationen, wenn ein ANR-Fehler auftritt. Bei älteren Betriebssystemversionen befindet sich eine einzelne /data/anr/traces.txt-Datei auf dem Gerät. Unter neueren Betriebssystemversionen gibt es mehrere /data/anr/anr_*-Dateien. Sie können von einem Gerät oder Emulator auf ANR-Traces zugreifen, indem Sie Android Debug Bridge (adb) als Root verwenden:

adb root
adb shell ls /data/anr
adb pull /data/anr/<filename>

Sie können einen Fehlerbericht von einem physischen Gerät erstellen, indem Sie entweder die Entwickleroption „Fehlerbericht erstellen“ auf dem Gerät oder den Befehl „adb Bugreport“ auf Ihrem Entwicklungscomputer verwenden. Weitere Informationen finden Sie unter Fehlerberichte erfassen und lesen.

Probleme beheben

Wenn Sie das Problem identifiziert haben, können Sie mithilfe der Tipps in diesem Abschnitt häufig auftretende Probleme beheben.

Langsamer Code im Hauptthread

Ermitteln Sie die Stellen im Code, an denen der Hauptthread der Anwendung länger als 5 Sekunden aktiv ist. Suchen Sie in Ihrer Anwendung nach verdächtigen Anwendungsfällen und versuchen Sie, den ANR-Fehler zu reproduzieren.

Abbildung 2 zeigt beispielsweise eine Traceview-Zeitachse, in der der Hauptthread länger als 5 Sekunden ausgelastet ist.

Abbildung 2. Traceview-Zeitachse mit einem ausgelasteten Hauptthread

Abbildung 2: TraceView-Zeitachse mit aktivem Hauptthread

In Abbildung 2 ist zu sehen, dass der größte Teil des problematischen Codes im onClick(View)-Handler erfolgt, wie im folgenden Codebeispiel gezeigt:

Kotlin

override fun onClick(v: View) {
    // This task runs on the main thread.
    BubbleSort.sort(data)
}

Java

@Override
public void onClick(View view) {
    // This task runs on the main thread.
    BubbleSort.sort(data);
}

In diesem Fall sollten Sie die Arbeit, die im Hauptthread ausgeführt wird, in einen Worker-Thread verschieben. Das Android Framework enthält Klassen, mit denen Aufgaben in einen Worker-Thread verschoben werden können. Weitere Informationen finden Sie unter Worker-Threads.

E/A im Hauptthread

Die Ausführung von E/A-Vorgängen im Hauptthread ist eine häufige Ursache für langsame Vorgänge im Hauptthread, was zu ANR-Fehlern führen kann. Es wird empfohlen, alle E/A-Vorgänge in einen Worker-Thread zu verschieben, wie im vorherigen Abschnitt gezeigt.

Einige Beispiele für E/A-Vorgänge sind Netzwerk- und Speichervorgänge. Weitere Informationen finden Sie unter Netzwerkvorgänge durchführen und Daten speichern.

Konflikt durch Sperre

In einigen Szenarien wird die Arbeit, die einen ANR-Fehler verursacht, nicht direkt im Hauptthread der Anwendung ausgeführt. Wenn ein Worker-Thread eine Sperre für eine Ressource enthält, die der Hauptthread zum Ausführen seiner Arbeit benötigt, kann ein ANR-Fehler auftreten.

Abbildung 4 zeigt beispielsweise eine Traceview-Zeitachse, in der die meiste Arbeit an einem Worker-Thread ausgeführt wird.

Abbildung 4. Traceview-Zeitachse, die die Arbeit zeigt, die an einem Worker-Thread ausgeführt wird

Abbildung 4: Traceview-Zeitachse, die die Arbeit zeigt, die an einem Worker-Thread ausgeführt wird

Wenn bei Ihren Nutzern jedoch weiterhin ANR-Fehler auftreten, sollten Sie sich den Status des Hauptthreads im Android-Gerätemonitor ansehen. Normalerweise hat der Hauptthread den Status RUNNABLE, wenn er zum Aktualisieren der UI bereit ist und im Allgemeinen reagiert.

Wenn der Hauptthread die Ausführung jedoch nicht fortsetzen kann, befindet er sich im Status BLOCKED und kann nicht auf Ereignisse reagieren. Der Status wird im Android-Gerätemonitor als Überwachen oder Warten angezeigt, wie in Abbildung 5 dargestellt.

Abbildung 5. Hauptthread im Monitor-Status

Abbildung 5: Hauptthread im Monitor-Status

Der folgende Trace zeigt den Hauptthread einer Anwendung, der beim Warten auf eine Ressource blockiert ist:

...
AsyncTask #2" prio=5 tid=18 Runnable
  | group="main" sCount=0 dsCount=0 obj=0x12c333a0 self=0x94c87100
  | sysTid=25287 nice=10 cgrp=default sched=0/0 handle=0x94b80920
  | state=R schedstat=( 0 0 0 ) utm=757 stm=0 core=3 HZ=100
  | stack=0x94a7e000-0x94a80000 stackSize=1038KB
  | held mutexes= "mutator lock"(shared held)
  at com.android.developer.anrsample.BubbleSort.sort(BubbleSort.java:8)
  at com.android.developer.anrsample.MainActivity$LockTask.doInBackground(MainActivity.java:147)
  - locked <0x083105ee> (a java.lang.Boolean)
  at com.android.developer.anrsample.MainActivity$LockTask.doInBackground(MainActivity.java:135)
  at android.os.AsyncTask$2.call(AsyncTask.java:305)
  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
  at java.lang.Thread.run(Thread.java:761)
...

Das Überprüfen des Trace kann Ihnen helfen, den Code zu finden, der den Hauptthread blockiert. Der folgende Code sorgt dafür, dass die Sperre beibehalten wird, die den Hauptthread im vorherigen Trace blockiert:

Kotlin

override fun onClick(v: View) {
    // The worker thread holds a lock on lockedResource
    LockTask().execute(data)

    synchronized(lockedResource) {
        // The main thread requires lockedResource here
        // but it has to wait until LockTask finishes using it.
    }
}

class LockTask : AsyncTask<Array<Int>, Int, Long>() {
    override fun doInBackground(vararg params: Array<Int>): Long? =
            synchronized(lockedResource) {
                // This is a long-running operation, which makes
                // the lock last for a long time
                BubbleSort.sort(params[0])
            }
}

Java

@Override
public void onClick(View v) {
    // The worker thread holds a lock on lockedResource
   new LockTask().execute(data);

   synchronized (lockedResource) {
       // The main thread requires lockedResource here
       // but it has to wait until LockTask finishes using it.
   }
}

public class LockTask extends AsyncTask<Integer[], Integer, Long> {
   @Override
   protected Long doInBackground(Integer[]... params) {
       synchronized (lockedResource) {
           // This is a long-running operation, which makes
           // the lock last for a long time
           BubbleSort.sort(params[0]);
       }
   }
}

Ein weiteres Beispiel ist der Hauptthread einer Anwendung, der auf ein Ergebnis eines Worker-Threads wartet, wie im folgenden Code dargestellt. Die Verwendung von wait() und notify() ist in Kotlin nicht empfohlen, da es eigene Mechanismen für die Verarbeitung von Nebenläufigkeit gibt. Wenn Sie Kotlin verwenden, sollten Sie nach Möglichkeit Kotlin-spezifische Mechanismen verwenden.

Kotlin

fun onClick(v: View) {
    val lock = java.lang.Object()
    val waitTask = WaitTask(lock)
    synchronized(lock) {
        try {
            waitTask.execute(data)
            // Wait for this worker thread’s notification
            lock.wait()
        } catch (e: InterruptedException) {
        }
    }
}

internal class WaitTask(private val lock: java.lang.Object) : AsyncTask<Array<Int>, Int, Long>() {
    override fun doInBackground(vararg params: Array<Int>): Long? {
        synchronized(lock) {
            BubbleSort.sort(params[0])
            // Finished, notify the main thread
            lock.notify()
        }
    }
}

Java

public void onClick(View v) {
   WaitTask waitTask = new WaitTask();
   synchronized (waitTask) {
       try {
           waitTask.execute(data);
           // Wait for this worker thread’s notification
           waitTask.wait();
       } catch (InterruptedException e) {}
   }
}

class WaitTask extends AsyncTask<Integer[], Integer, Long> {
   @Override
   protected Long doInBackground(Integer[]... params) {
       synchronized (this) {
           BubbleSort.sort(params[0]);
           // Finished, notify the main thread
           notify();
       }
   }
}

Es gibt einige andere Situationen, in denen der Hauptthread blockiert werden kann, einschließlich Threads, die Lock, Semaphore verwenden, sowie einen Ressourcenpool (z. B. ein Pool von Datenbankverbindungen) oder andere Mechanismen zum gegenseitigen Ausschluss (Mutex).

Sie sollten die Sperren Ihrer Anwendung für Ressourcen im Allgemeinen bewerten. Wenn Sie jedoch ANR-Fehler vermeiden möchten, sollten Sie sich die Sperren für Ressourcen ansehen, die vom Hauptthread benötigt werden.

Achten Sie darauf, dass die Sperren für mindestens so lange gehalten werden, wie noch besser, prüfen Sie, ob die Anwendung den Hold überhaupt erst benötigt. Wenn Sie anhand der Sperre bestimmen, wann die UI basierend auf der Verarbeitung eines Worker-Threads aktualisiert werden soll, verwenden Sie Mechanismen wie onProgressUpdate() und onPostExecute() für die Kommunikation zwischen dem Worker- und dem Hauptthread.

Deadlocks

Ein Deadlock tritt auf, wenn ein Thread in einen Wartestatus wechselt, weil eine erforderliche Ressource von einem anderen Thread gehalten wird, der ebenfalls auf eine Ressource des ersten Threads wartet. Wenn sich der Hauptthread der App in dieser Situation befindet, treten wahrscheinlich ANR-Fehler auf.

Deadlocks sind ein gut erforschtes Phänomen in der Informatik und es gibt Algorithmen zum Deadlock-Schutz, mit denen Sie Deadlocks vermeiden können.

Weitere Informationen finden Sie auf der Wikipedia unter Deadlock und Deadlock-Präventionsalgorithmen.

Langsame Empfänger

Apps können über Übertragungsempfänger auf Broadcast-Nachrichten reagieren, z. B. beim Aktivieren oder Deaktivieren des Flugmodus oder einer Änderung des Verbindungsstatus. Ein ANR-Fehler tritt auf, wenn die Verarbeitung der Broadcast-Nachricht durch eine App zu lange dauert.

Ein ANR-Fehler tritt in den folgenden Fällen auf:

  • Ein Sendeempfänger hat die Ausführung seiner Methode onReceive() nicht innerhalb eines erheblichen Zeitraums abgeschlossen.
  • Ein Broadcast-Empfänger ruft goAsync() auf und schlägt finish() für das PendingResult-Objekt auf.

Deine Anwendung sollte in der Methode onReceive() einer BroadcastReceiver nur kurze Vorgänge ausführen. Wenn Ihre Anwendung jedoch aufgrund einer Broadcast-Nachricht eine komplexere Verarbeitung erfordert, sollten Sie die Aufgabe auf ein IntentService verschieben.

Mit Tools wie Traceview können Sie feststellen, ob Ihr Broadcast-Empfänger lang andauernde Vorgänge im Hauptthread der Anwendung ausführt. Abbildung 6 zeigt beispielsweise die Zeitachse eines Broadcast-Empfängers, der eine Nachricht im Hauptthread etwa 100 Sekunden lang verarbeitet.

Abbildung 6. Traceview-Zeitachse, die die BroadcastReceiver-Arbeit im Hauptthread zeigt

Abbildung 6: Traceview-Zeitachse, die die BroadcastReceiver-Arbeit im Hauptthread zeigt

Dieses Verhalten kann durch lang andauernde Vorgänge mit der Methode onReceive() des BroadcastReceiver verursacht werden, wie im folgenden Beispiel gezeigt:

Kotlin

override fun onReceive(context: Context, intent: Intent) {
    // This is a long-running operation
    BubbleSort.sort(data)
}

Java

@Override
public void onReceive(Context context, Intent intent) {
    // This is a long-running operation
    BubbleSort.sort(data);
}

In Situationen wie diesen wird empfohlen, den Vorgang mit langer Ausführungszeit in einen IntentService zu verschieben, da er einen Worker-Thread zur Ausführung seiner Arbeit verwendet. Der folgende Code zeigt, wie ein IntentService zum Verarbeiten eines lang andauernden Vorgangs verwendet wird:

Kotlin

override fun onReceive(context: Context, intent: Intent) {
    Intent(context, MyIntentService::class.java).also { intentService ->
        // The task now runs on a worker thread.
        context.startService(intentService)
    }
}

class MyIntentService : IntentService("MyIntentService") {
    override fun onHandleIntent(intent: Intent?) {
        BubbleSort.sort(data)
    }
}

Java

@Override
public void onReceive(Context context, Intent intent) {
    // The task now runs on a worker thread.
    Intent intentService = new Intent(context, MyIntentService.class);
    context.startService(intentService);
}

public class MyIntentService extends IntentService {
   @Override
   protected void onHandleIntent(@Nullable Intent intent) {
       BubbleSort.sort(data);
   }
}

Bei Verwendung von IntentService wird der Vorgang mit langer Ausführungszeit in einem Worker-Thread und nicht im Hauptthread ausgeführt. Abbildung 7 zeigt die auf den Worker-Thread übertragene Arbeit in der Traceview-Zeitachse.

Abbildung 7. Traceview-Zeitachse, die die in einem Worker-Thread verarbeitete Broadcast-Nachricht zeigt

Abbildung 7: Traceview-Zeitachse, die die in einem Worker-Thread verarbeitete Broadcast-Nachricht zeigt

Der Empfänger des Rundfunks kann dem System mit goAsync() signalisieren, dass er mehr Zeit zur Verarbeitung der Nachricht benötigt. Sie sollten jedoch finish() für das PendingResult-Objekt aufrufen. Das folgende Beispiel zeigt, wie „Finish()“ aufgerufen wird, damit das System den Broadcast-Empfänger wiederverwenden und einen ANR-Fehler vermeiden kann:

Kotlin

val pendingResult = goAsync()

object : AsyncTask<Array<Int>, Int, Long>() {
    override fun doInBackground(vararg params: Array<Int>): Long? {
        // This is a long-running operation
        BubbleSort.sort(params[0])
        pendingResult.finish()
        return 0L
    }
}.execute(data)

Java

final PendingResult pendingResult = goAsync();
new AsyncTask<Integer[], Integer, Long>() {
   @Override
   protected Long doInBackground(Integer[]... params) {
       // This is a long-running operation
       BubbleSort.sort(params[0]);
       pendingResult.finish();
   }
}.execute(data);

Wenn Sie den Code jedoch von einem langsamen Broadcast-Empfänger in einen anderen Thread verschieben und goAsync() verwenden, wird der ANR-Fehler nicht behoben, wenn die Übertragung im Hintergrund ausgeführt wird. Das ANR-Zeitlimit gilt weiterhin.

Spielaktivität

Die Bibliothek GameActivity hat in Fallstudien von Spielen und Apps, die in C oder C++ geschrieben sind, reduzierte ANR-Fehler. Wenn Sie Ihre vorhandene native Aktivität durch GameActivity ersetzen, können Sie die Blockierung von UI-Threads reduzieren und damit verhindern, dass einige ANR-Fehler auftreten.

Weitere Informationen zu ANRs findest du unter App responsiv halten. Weitere Informationen zu Threads finden Sie unter Threading-Leistung.