App-Fehler beheben

Android Studio bietet einen Debugger, der Ihnen unter anderem folgende Möglichkeiten bietet:

  • Wähle ein Gerät aus, auf dem du das Debugging deiner App verwenden möchtest.
  • Setze Haltepunkte in deinem Java-, Kotlin- und C/C++-Code.
  • Variablen untersuchen und Ausdrücke zur Laufzeit auswerten

Diese Seite enthält eine Anleitung für grundlegende Debugger-Vorgänge. Weitere Informationen finden Sie in den IntelliJ IDEA-Debugging-Dokumenten.

Fehlerbehebung aktivieren

Führen Sie die folgenden Schritte aus, bevor Sie mit der Fehlerbehebung beginnen:

Aktiviere die Fehlerbehebung auf deinem Gerät.
Wenn Sie den Emulator verwenden, ist die Fehlerbehebung standardmäßig aktiviert. Für ein verbundenes Gerät musst du jedoch die Fehlerbehebung in den Geräteentwickleroptionen aktivieren.
Führen Sie eine debugfähige Build-Variante aus.

Verwenden Sie eine Build-Variante, die debuggable true (isDebuggable = true in Kotlin-Skripts) enthält.

Normalerweise kannst du die Standardvariante zum Debuggen auswählen, die in jedem Android Studio-Projekt enthalten ist, auch wenn sie in der Datei build.gradle nicht sichtbar ist. Wenn Sie jedoch neue Build-Typen definieren, die debugfähig sein sollen, müssen Sie dem Build-Typ debuggable true hinzufügen:

Groovig

android {
    buildTypes {
        customDebugType {
            debuggable true
            ...
        }
    }
}

Kotlin

android {
    buildTypes {
        create("customDebugType") {
            isDebuggable = true
            ...
        }
    }
}

Diese Eigenschaft gilt auch für Module mit C-/C++-Code.

Hinweis: Die Eigenschaft jniDebuggable wird nicht mehr verwendet.

Wenn Ihre Anwendung von einem Bibliotheksmodul abhängig ist, das Sie ebenfalls debuggen möchten, muss diese Bibliothek ebenfalls mit debuggable true verpackt sein, damit ihre Symbole zur Fehlerbehebung erhalten bleiben. Damit die debugfähigen Varianten Ihres App-Projekts die debugfähige Variante eines Bibliotheksmoduls erhalten, sollten Sie Nicht-Standardversionen Ihrer Bibliothek veröffentlichen.

Fehlerbehebung starten

So starten Sie eine Debugging-Sitzung:

  1. Lege Haltepunkte im Code deiner App fest.
  2. Wählen Sie in der Symbolleiste im Menü für das Zielgerät das Gerät aus, auf dem Sie das Debugging Ihrer App ausführen möchten.
    Menü für Zielgerät.
    Abbildung 1: Menü des Zielgeräts.

    Wenn Sie keine Geräte konfiguriert haben, müssen Sie entweder ein Gerät über USB verbinden, ein Gerät über WLAN verbinden oder ein AVD erstellen, um den Android-Emulator zu verwenden.

  3. Klicken Sie in der Symbolleiste auf Fehlerbehebung .

    Wenn die Anwendung bereits auf dem Gerät ausgeführt wird, wird ein Dialogfeld angezeigt, in dem Sie gefragt werden, ob Sie von „Ausführen“ zu „Debug“ wechseln möchten. Das Gerät muss neu gestartet werden, um mit der Fehlerbehebung beginnen zu können. Klicken Sie auf Fehlerbehebung abbrechen und hängen Sie den Debugger an eine laufende App an, damit dieselbe Instanz der App weiter ausgeführt wird. Andernfalls erstellt Android Studio ein APK, signiert es mit einem Schlüssel zur Fehlerbehebung, installiert es auf dem ausgewählten Gerät und führt es aus.

    Wenn Sie Ihrem Projekt C- und C++-Code hinzufügen, führt Android Studio im Debug-Fenster auch den LLDB-Debugger aus, um Ihren nativen Code zu debuggen.

  4. Falls das Fenster zur Fehlerbehebung nicht geöffnet ist, wählen Sie Ansicht > Toolfenster > Fehlerbehebung aus oder klicken Sie in der Symbolleiste des Fensters auf Fehler beheben .

Debugger an eine laufende Anwendung anhängen

Wenn die App bereits auf dem Gerät ausgeführt wird, können Sie mit dem Debugging beginnen, ohne die App neu zu starten. Gehen Sie dazu so vor:

  1. Klicken Sie auf Debugger an Android-Prozess anhängen .
  2. Wählen Sie im Dialogfeld Prozess auswählen den Prozess aus, an den Sie den Debugger anhängen möchten.
    1. Wenn du einen Emulator oder ein gerootetes Gerät verwendest, kannst du Alle Prozesse anzeigen aktivieren, um alle Prozesse zu sehen. Auf einem gerooteten Gerät werden hier alle Prozesse angezeigt, die auf dem Gerät ausgeführt werden. Auf einem nicht gerooteten Gerät werden jedoch nur debug-fähige Prozesse angezeigt.
    2. Im Menü Android Debugger-Einstellungen verwenden können Sie eine vorhandene Ausführungs-/Fehlerbehebungskonfiguration auswählen. So können Sie für C- und C++-Code die LLDB-Startbefehle, die LLDB-Post-Attach-Befehle und die Symbolverzeichnisse in einer vorhandenen Konfiguration wiederverwenden.
    3. Wenn Sie noch keine Ausführungs-/Fehlerbehebungskonfiguration haben, wählen Sie Neu erstellen aus. Dadurch wird das Menü Art der Fehlerbehebung aktiviert, in dem Sie einen anderen Fehlerbehebungstyp auswählen können. Standardmäßig verwendet Android Studio den Debug-Typ „Automatisch erkennen“, um die beste Debugger-Option für Sie auszuwählen – je nachdem, ob Ihr Projekt Java- oder C/C++-Code enthält.
  3. Klicke auf OK.

    Das Fenster für die Fehlerbehebung wird angezeigt.

Auf dem Tab Prozesse im Geräte-Explorer (Ansicht > Toolfenster > Geräte-Explorer) finden Sie auch eine Liste der Debug-fähigen Prozesse. Dort können Sie einen Prozess auswählen und ein Beenden ausführen, das Beenden von erzwingen oder den Debugger an einen bestimmten Prozess anhängen.

Das Debug-Fenster

Abbildung 2: Das Debug-Fenster.

Das Debug-Fenster ist in

  1. Ausführungs- und Navigationssymbolleiste siehe Mit Haltepunkten arbeiten
  2. Thread-Auswahl
  3. Eintrag für Auswertung und Watch-Ausdruck. Siehe Variablen prüfen.
  4. Stapelanzeige
  5. Variablen. Siehe Variablen prüfen.

Hinweis:Der Android Studio-Debugger und die automatische Speicherbereinigung sind lose integriert. Die virtuelle Android-Maschine sorgt dafür, dass ein Objekt, das der Debugger erkennt, erst dann automatisch bereinigt wird, wenn die Verbindung zum Debugger getrennt wird. Dies kann dazu führen, dass Objekte angesammelt werden, während der Debugger verbunden ist. Wenn der Debugger beispielsweise einen laufenden Thread erkennt, wird das zugehörige Thread-Objekt erst dann automatisch bereinigt, wenn die Verbindung des Debuggers getrennt wird, selbst wenn der Thread beendet wurde.

Debuggertyp ändern

Da für das Debuggen von Java-/Kotlin-Code und C/C++-Code verschiedene Debugger-Tools erforderlich sind, können Sie mit dem Android Studio-Debugger auswählen, welcher Debuggertyp verwendet werden soll. Welcher Debugger verwendet wird, richtet sich standardmäßig nach den Sprachen, die in Ihrem Projekt erkannt werden. Dazu wird der Debuggertyp Automatisch erkennen verwendet.

Um den Debugger in der Fehlerbehebungskonfiguration manuell auszuwählen, klicken Sie auf Ausführen > Konfigurationen bearbeiten. Sie können den Debugger auch in dem Dialogfeld auswählen, das angezeigt wird, wenn Sie auf Ausführen > Debugger an Android-Prozess anhängen klicken.

Folgende Fehlerbehebungstypen sind verfügbar:

Automatisch erkennen
Wählen Sie diesen Debug-Typ aus, wenn Android Studio automatisch die beste Option für den Code auswählen soll, für den Sie eine Fehlerbehebung durchführen. Wenn Ihr Projekt beispielsweise C- oder C++-Code enthält, verwendet Android Studio automatisch den Typ „Dual Debug“. Andernfalls verwendet Android Studio den Fehlerbehebungstyp „Nur Java“.
Nur Java
Wählen Sie diesen Debug-Typ aus, wenn Sie nur Code debuggen möchten, der in Java oder Kotlin geschrieben wurde. Der Nur-Java-Debugger ignoriert alle Haltepunkte oder Watches, die Sie in Ihrem nativen Code festgelegt haben.
Nur nativ (nur mit C-/C++-Code verfügbar)
Wählen Sie diesen Typ zur Fehlerbehebung aus, wenn Sie nur LLDB zum Debuggen des Codes verwenden möchten. Wenn Sie diesen Debug-Typ verwenden, ist die Java-Debugger-Sitzungsansicht nicht verfügbar. Standardmäßig prüft LLDB nur Ihren nativen Code und ignoriert Haltepunkte in Ihrem Java-Code. Wenn Sie auch Ihren Java-Code debuggen möchten, wechseln Sie entweder zum Typ „Automatisch erkennen“ oder „Duale Fehlerbehebung“.

Das native Debugging funktioniert nur auf Geräten, die die folgenden Anforderungen erfüllen:

  • Das Gerät unterstützt run-as.

    Um zu prüfen, ob das Gerät run-as unterstützt, führen Sie den folgenden Befehl in der ADB-Shell aus, die mit Ihrem Gerät verbunden ist:

    run-as your-package-name pwd
    

    Ersetzen Sie your-package-name durch den Paketnamen Ihrer App. Wenn das Gerät run-as unterstützt, sollte der Befehl ohne Fehler zurückgegeben werden.

  • Auf dem Gerät ist ptrace aktiviert.

    Um zu prüfen, ob ptrace aktiviert ist, führen Sie den folgenden Befehl in der ADB-Shell aus, die mit Ihrem Gerät verbunden ist:

    sysctl kernel.yama.ptrace_scope
    

    Wenn ptrace aktiviert ist, gibt der Befehl den Wert 0 oder einen unknown key-Fehler aus. Wenn ptrace nicht aktiviert ist, wird ein anderer Wert als 0 ausgegeben.

Dual (Java und nativ) – nur mit C/C++-Code verfügbar
Wählen Sie diesen Debug-Typ aus, wenn Sie zwischen der Fehlerbehebung in Java und nativem Code wechseln möchten. In Android Studio werden sowohl der Java-Debugger als auch LLDB an den App-Prozess angehängt, sodass Sie Haltepunkte sowohl in Ihrem Java- als auch im nativen Code prüfen können, ohne die App neu zu starten oder die Fehlerbehebungskonfiguration zu ändern.

In Abbildung 2 sehen Sie die beiden Tabs rechts neben dem Titel des Debug-Fensters. Da die Anwendung sowohl Java- als auch C++-Code enthält, dient ein Tab zum Debugging des nativen Codes und der andere zum Debuggen von Java-Code, wie durch -java angegeben.

Abbildung 3: Tab für das Debugging von nativem Code und Tab für das Debugging von Java-Code.

Hinweis: Beim Debuggen von nativem Code, der vom Compiler optimiert wurde, wird möglicherweise die folgende Warnmeldung angezeigt:
This function was compiled with optimizations enabled. Some debugger features may not be available. Wenn Sie Optimierungs-Flags verwenden, nimmt der Compiler Änderungen an Ihrem kompilierten Code vor, um ihn effizienter auszuführen. Dies kann dazu führen, dass der Debugger unerwartete oder falsche Informationen meldet, da es für ihn schwierig ist, den optimierten kompilierten Code dem ursprünglichen Quellcode zuzuordnen. Aus diesem Grund sollten Sie beim Debuggen Ihres nativen Codes die Compiler-Optimierungen deaktivieren.

Systemprotokoll verwenden

Das Systemprotokoll zeigt Systemmeldungen an, während Sie Ihre App debuggen. Diese Meldungen enthalten Informationen von Anwendungen, die auf dem Gerät ausgeführt werden. Wenn Sie das Systemlog zum Debuggen der Anwendung verwenden möchten, müssen Sie dafür sorgen, dass Ihr Code Logeinträge schreibt und den Stacktrace für Ausnahmen ausgibt, während sich Ihre Anwendung in der Entwicklungsphase befindet.

Logeinträge in den Code schreiben

Verwenden Sie die Klasse Log, um Logeinträge in Ihren Code zu schreiben. Lognachrichten helfen Ihnen, den Ausführungsablauf besser zu verstehen, da sie die Debug-Ausgabe des Systems erfassen, während Sie mit Ihrer Anwendung interagieren. Sie können auch darüber informieren, bei welchem Teil der Anwendung Fehler aufgetreten sind. Weitere Informationen zum Logging finden Sie unter Logs mit Logcat schreiben und ansehen.

Das folgende Beispiel zeigt, wie Sie Lognachrichten hinzufügen können, um zu ermitteln, ob zu Beginn der Aktivität Informationen zum vorherigen Status verfügbar sind:

Kotlin

import android.util.Log
...
class MyActivity : Activity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state")
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available")
            /* initialize app */
        }
        ...
    }
  ...
  companion object {
    private val TAG: String = MyActivity::class.java.simpleName
    ...
  }
}

Java

import android.util.Log;
...
public class MyActivity extends Activity {
    private static final String TAG = MyActivity.class.getSimpleName();
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
       ...
       if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state");
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available");
            /* initialize app */
        }
        ...
    }
}

Während der Entwicklung kann Ihr Code auch Ausnahmen abfangen und den Stacktrace in das Systemlog schreiben:

Kotlin

fun someOtherMethod() {
    try {
        ...
    } catch (e : SomeException) {
        Log.d(TAG, "someOtherMethod()", e)
    }
}

Java

void someOtherMethod() {
    try {
        ...
    } catch (SomeException e) {
        Log.d(TAG, "someOtherMethod()", e);
    }
}

Hinweis:Entfernen Sie Debug-Logmeldungen und Stacktrace-Druckaufrufe aus dem Code, wenn Sie die Anwendung veröffentlichen möchten. Legen Sie dazu das Flag DEBUG fest und platzieren Sie Debug-Logmeldungen in bedingte Anweisungen.

Systemprotokoll aufrufen

Sie können die Fehlerbehebung und andere Systemmeldungen im Logcat-Fenster ansehen und filtern (siehe Abbildung 4). Sie sehen beispielsweise Nachrichten bei einer automatischen Speicherbereinigung oder Nachrichten, die Sie Ihrer Anwendung mit der Klasse Log hinzufügen.

Wenn Sie Logcat verwenden möchten, starten Sie das Debugging und wählen Sie den Tab „Logcat“ aus.

Abbildung 4: Logcat-Fenster mit Filtereinstellungen.

Eine Beschreibung von Logcat und seinen Filteroptionen finden Sie unter Logs mit Logcat schreiben und ansehen.

Mit Haltepunkten arbeiten

Android Studio unterstützt Haltepunkte, die verschiedene Debugging-Aktionen auslösen. Es gibt verschiedene Arten von Haltepunkten:

Zeilenhaltepunkt
Der gängigste Typ ist ein Zeilenhaltepunkt, mit dem die Ausführung der Anwendung in einer bestimmten Codezeile pausiert wird. Im pausierten Zustand können Sie Variablen untersuchen, Ausdrücke auswerten und dann die Ausführung Zeile für Zeile fortsetzen, um die Ursachen von Laufzeitfehlern zu ermitteln.
Haltepunkt für Methode
Ein Methodenhaltepunkt pausiert die Ausführung der Anwendung, wenn eine bestimmte Methode erreicht oder beendet wird. Im pausierten Zustand können Sie Variablen untersuchen, Ausdrücke auswerten und dann die Ausführung Zeile für Zeile fortsetzen, um die Ursachen von Laufzeitfehlern zu ermitteln. Wenn Sie einen Haltepunkt für eine zusammensetzbare Funktion festlegen, werden im Debugger die Parameter der zusammensetzbaren Funktion und ihr Status aufgelistet. So können Sie leichter feststellen, welche Änderungen die Neuzusammensetzung verursacht haben könnten.
Haltepunkt für Feld
Ein Feldhaltepunkt pausiert die Ausführung der Anwendung, wenn aus einem Feld gelesen oder in ein bestimmtes Feld geschrieben wird.
Haltepunkt für Ausnahme
Ein Haltepunkt für Ausnahmen pausiert die Ausführung Ihrer App, wenn eine Ausnahme ausgelöst wird.

Sie können bedingte Haltepunkte festlegen, die die Ausführung nur anhalten, wenn bestimmte Bedingungen erfüllt sind. Sie können auch Logging-Haltepunkte festlegen, die in Logcat schreiben, ohne die Ausführung anzuhalten. So vermeiden Sie, dass Ihr Code mit Logberichten überfrachtet wird.

So fügen Sie einen Zeilenhaltepunkt hinzu:

  1. Suchen Sie die Codezeile, in der Sie die Ausführung anhalten möchten.
  2. Klicken Sie auf den linken Spaltenabstand entlang dieser Codezeile oder platzieren Sie das Caret-Zeichen in der Zeile und drücken Sie Strg + F8 (unter macOS Befehlstaste + F8).
  3. Wenn Ihre App bereits ausgeführt wird, klicken Sie auf Debugger an Android-Prozess anhängen . Klicken Sie andernfalls auf Fehlerbehebung , um mit der Fehlerbehebung zu beginnen.

Neben der Linie wird ein roter Punkt angezeigt, wenn Sie einen Haltepunkt festlegen (siehe Abbildung 5).

Abbildung 5: Neben der Linie wird ein roter Punkt angezeigt, wenn Sie einen Haltepunkt festlegen.

Wenn die Codeausführung den Haltepunkt erreicht, pausiert Android Studio die Ausführung der App.

Verwenden Sie die Tools auf dem Tab „Debugger“, um den Status der Anwendung zu ermitteln:

  • Wenn Sie die Objektstruktur auf eine Variable prüfen möchten, maximieren Sie sie in der Ansicht „Variablen“. Wenn die Ansicht „Variablen“ nicht angezeigt wird, klicken Sie auf Layouteinstellungen und prüfen Sie, ob Variablen aktiviert ist.

  • Wenn Sie zur nächsten Codezeile wechseln möchten, ohne eine Methode einzugeben, klicken Sie auf Step Over .

  • Um zur ersten Zeile innerhalb eines Methodenaufrufs zu gelangen, klicken Sie auf Step Into .

  • Um zur nächsten Zeile außerhalb der aktuellen Methode zu gelangen, klicken Sie auf Ausstieg .

  • Um die App weiterhin normal auszuführen, klicke auf Programm fortsetzen .

Wenn Ihr Projekt nativen Code verwendet, hängt der Debug-Typ „Automatisch erkennen“ standardmäßig als zwei separate Prozesse an Ihre Anwendung an. Sie können zwischen der Prüfung von Java- und C/C++-Haltpunkten wechseln, ohne die Anwendung neu zu starten oder Einstellungen zu ändern.

Hinweis:Damit Android Studio Haltepunkte in Ihrem C- oder C++-Code erkennen kann, müssen Sie einen Fehlerbehebungstyp verwenden, der LLDB unterstützt, z. B. „Automatisch erkennen“, „Nativ“ oder „Dual“. Sie können den in Android Studio verwendeten Fehlerbehebungstyp ändern, indem Sie Ihre Fehlerbehebungskonfiguration bearbeiten. Weitere Informationen zu den verschiedenen Fehlerbehebungstypen finden Sie im Abschnitt zu anderen Fehlerbehebungstypen.

Wenn Android Studio Ihre App auf Ihrem Zielgerät bereitstellt, wird das Fenster „Fehlerbehebung“ mit einem Tab oder einer Ansicht der Fehlerbehebungssitzung für jeden Debugger-Prozess geöffnet (siehe Abbildung 6).

Abbildung 6: Debugging von nativem Code mit LLDB
  1. Android Studio wechselt zum Tab <your-module>, wenn der LLDB-Debugger in deinem C-/C++-Code einen Haltepunkt findet. Die Bereiche Frames, Variablen und Watches sind ebenfalls verfügbar und funktionieren genau wie beim Debuggen von Java-Code.

    Obwohl der Thread-Bereich in der LLDB-Sitzungsansicht nicht verfügbar ist, können Sie über die Liste im Frames-Bereich auf Ihre App-Prozesse zugreifen. Weitere Informationen zu diesen Bereichen finden Sie in den Abschnitten zum Debuggen von Window Frames und Prüfen von Variablen.

    Hinweis: Während der Prüfung eines Haltepunkts in Ihrem nativen Code hält das Android-System die virtuelle Maschine an, auf der der Java-Bytecode Ihrer Anwendung ausgeführt wird. Das bedeutet, dass Sie während der Prüfung eines Haltepunkts in Ihrem nativen Code nicht mit dem Java-Debugger interagieren oder Statusinformationen aus Ihrer Java-Debugger-Sitzung abrufen können.

  2. Android Studio wechselt zum Tab <your-module>-Java, wenn der Java-Debugger einen Haltepunkt in deinem Java- oder Kotlin-Code findet.
  3. Beim Debugging mit LLDB können Sie das LLDB-Terminal in der LLDB-Sitzungsansicht verwenden, um Befehlszeilenoptionen an LLDB zu übergeben. Wenn bestimmte Befehle von LLDB bei jedem Start des Debuggings für Ihre Anwendung ausgeführt werden sollen – entweder kurz vor oder direkt nach dem Hinzufügen des Debuggers an den Anwendungsprozess –, können Sie diese Befehle Ihrer Fehlerbehebungskonfiguration hinzufügen.

Beim Debuggen von C-/C++-Code können Sie auch spezielle Arten von Haltepunkten festlegen, sogenannte Watchpoints. Diese können den Anwendungsprozess anhalten, wenn die Anwendung mit einem bestimmten Speicherblock interagiert. Weitere Informationen finden Sie im Abschnitt zum Hinzufügen von Watchpoints.

Haltepunkte ansehen und konfigurieren

Klicken Sie im Debug-Fenster auf Haltepunkte ansehen , um alle Haltepunkte anzusehen und die Haltepunkteinstellungen zu konfigurieren. Das Fenster „Breakpoints“ wird angezeigt (siehe Abbildung 7).

Abbildung 7. Das Fenster „Breakpoints“ listet alle aktuellen Haltepunkte auf und enthält für jeden Haltepunkt Verhaltenseinstellungen.

Im Fenster „Breakpoints“ können Sie die einzelnen Haltepunkte in der Liste im Bereich aktivieren oder deaktivieren. Wenn ein Haltepunkt deaktiviert ist, pausiert Android Studio die App nicht, wenn dieser Haltepunkt erreicht wird.

Wählen Sie aus der Liste einen Haltepunkt aus, um seine Einstellungen zu konfigurieren. Sie können einen Haltepunkt so konfigurieren, dass er zuerst deaktiviert wird, und das System ihn aktivieren lassen, sobald ein anderer Haltepunkt erreicht wird. Sie können auch konfigurieren, ob ein Haltepunkt nach dessen Treffer deaktiviert werden soll. Wenn Sie für eine Ausnahme einen Haltepunkt festlegen möchten, wählen Sie in der Liste der Haltepunkte Ausnahmehaltepunkte aus.

Klicken Sie im Fehlerbehebungsfenster auf Haltepunkte stummschalten , um alle Haltepunkte vorübergehend zu deaktivieren. Klicken Sie noch einmal, um sie wieder zu aktivieren.

Fehler im Fensterrahmen beheben

Im Debugger-Fenster können Sie im Frames-Bereich den Stapelframe untersuchen, der den aktuellen Haltepunkt ausgelöst hat. Auf diese Weise können Sie im Stackframe navigieren und diesen untersuchen sowie die Liste der Threads in Ihrer Android-App prüfen.

Wenn Sie einen Thread auswählen möchten, verwenden Sie das Thread-Auswahlmenü und sehen Sie sich den zugehörigen Stack-Frame an. Klicken Sie auf die Elemente im Frame, um die Quelle im Editor zu öffnen. Sie können auch die Darstellung der Threads anpassen und den Stapelframe exportieren, wie im Leitfaden zum Untersuchen von Frames beschrieben.

Variablen prüfen

Im Debugger-Fenster können Sie im Variablenbereich die Variablen prüfen, wenn das System Ihre App an einem Haltepunkt beendet und Sie einen Frame aus dem Frames-Bereich auswählen. Im Bereich „Variablen“ können Sie auch Ad-hoc-Ausdrücke mit statischen Methoden und/oder Variablen bewerten, die im ausgewählten Frame verfügbar sind.

So fügen Sie der Objektstruktur einen Ausdruck hinzu (während das Debugging der Anwendung ausgeführt wird):

Abbildung 8: Eingabefeld für die Objektstruktur und den Ausdruck im Fenster „Fehlerbehebung“
  1. Geben Sie den Ausdruck ein, der beobachtet oder angezeigt werden soll
  2. Klicken Sie auf Zu Smartwatches hinzufügen oder drücken Sie die Eingabetaste, um den Ausdruck einmal auszuwerten.

Wenn die Objektstruktur den Ausdruck enthält, den Sie beobachten möchten, können Sie ihn alternativ an den Anfang der Baumstruktur ziehen, um ihn als überwachten Ausdruck hinzuzufügen.

Beobachtete Ausdrücke werden aktualisiert, wenn Haltepunkte erreicht werden oder Sie den Code durchgehen.

Ausgewertete Ausdrücke werden so lange oben in der Objektstruktur angezeigt, bis Sie einen anderen Ausdruck manuell auswerten oder Ihren Code durchgehen.

Wenn Sie einen beobachteten Ausdruck aus der Objektstruktur entfernen möchten, klicken Sie mit der rechten Maustaste auf den Ausdruck und dann auf Smartwatch entfernen.

Watchpoints hinzufügen

Beim Debuggen von C/C++-Code können Sie spezielle Arten von Haltepunkten festlegen, sogenannte Watchpoints, die den Anwendungsprozess anhalten können, wenn die Anwendung mit einem bestimmten Speicherblock interagiert. Wenn Sie beispielsweise zwei Zeiger auf einen Speicherblock setzen und ihm einen Watchpoint zuweisen, löst die Verwendung eines jeden Zeigers für den Zugriff auf diesen Speicherblock den Watchpoint aus.

In Android Studio können Sie während der Laufzeit einen Watchpoint erstellen, indem Sie eine bestimmte Variable auswählen. LLDB weist den Watchpoint jedoch nur dem Arbeitsspeicherblock zu, den das System dieser Variable zuweist, nicht der Variablen selbst. Dies unterscheidet sich vom Hinzufügen einer Variablen zum Bereich „Uhren“, mit der Sie den Wert einer Variablen beobachten können, aber Ihren App-Prozess nicht anhalten können, wenn das System seinen Wert im Speicher liest oder ändert.

Hinweis: Wenn im Anwendungsprozess eine Funktion beendet wird und das System die lokalen Variablen aus dem Arbeitsspeicher hebt, müssen Sie alle Watchpoints, die Sie für diese Variablen erstellt haben, neu zuweisen.

Wenn Sie einen Watchpoint einrichten möchten, müssen Sie die folgenden Anforderungen erfüllen:

  • Das physische Zielgerät oder der Emulator verwendet eine x86- oder x86_64-CPU. Wenn Ihr Gerät eine ARM-CPU verwendet, müssen Sie die Grenze der Adresse Ihrer Variablen im Arbeitsspeicher entweder auf 4 Byte bei 32-Bit-Prozessoren oder auf 8 Byte bei 64-Bit-Prozessoren ausrichten. Wenn Sie eine Variable in Ihrem nativen Code ausrichten möchten, geben Sie in der Variablenverlangsamung __attribute__((aligned(num_bytes))) an:
    // For a 64-bit ARM processor
    int my_counter __attribute__((aligned(8)));
    
  • Sie haben bereits drei oder weniger Watchpoints zugewiesen. Android Studio unterstützt nur bis zu vier Watchpoints auf x86- oder x86_64-Zielgeräten. Andere Geräte unterstützen möglicherweise weniger Watchpoints.

Hinweis:Wenn Sie Fehler in Ihrer App mit 32-Bit-ARM-ABIs beheben, können Sie einen Absturz verursachen, wenn Sie einen Watchpoint hinzufügen oder den Mauszeiger auf Variablen im Code bewegen, um deren Werte zu untersuchen. Beheben Sie das Problem mit dem 64-Bit-ARM-, x86- oder x86_64-Binärprogramm. Dieses Problem wird in einer künftigen Android Studio-Version behoben.

Wenn Sie die Anforderungen erfüllen, können Sie so einen Watchpoint hinzufügen:

  1. Rufen Sie in der LLDB-Sitzungsansicht den Bereich „Variablen“ auf, während die Anwendung an einem Haltepunkt gesperrt ist.
  2. Klicken Sie mit der rechten Maustaste auf eine Variable, die den zu erfassenden Speicherblock belegt, und wählen Sie Watchpoint hinzufügen aus.

    Abbildung 9. Fügen Sie einer Variablen im Arbeitsspeicher einen Watchpoint hinzu.
  3. Es wird ein Dialogfeld zum Konfigurieren des Watchpoint angezeigt (siehe Abbildung 9).

    Konfigurieren Sie Ihren Watchpoint mit den folgenden Optionen:

    • Aktiviert:Deaktiviere diese Option, wenn Android Studio den Watchpoint ignorieren soll, bis du die Einstellung änderst. In Android Studio wird dein Watchpoint gespeichert, damit du später darauf zugreifen kannst.
    • Anhalten:Standardmäßig hält das Android-System den App-Prozess an, wenn es auf einen Arbeitsspeicherblock zugreift, den Sie einem Watchpoint zuweisen. Deaktivieren Sie diese Option, wenn Sie dieses Verhalten nicht wünschen. Dadurch werden zusätzliche Optionen angezeigt, mit denen Sie das Verhalten anpassen können, wenn das System mit Ihrem Watchpoint interagiert: Nachricht in Konsole protokollieren und Bei Treffer entfernen.
    • Access Type (Zugriffstyp): Wählen Sie aus, ob die App den Watchpoint auslösen soll, wenn sie versucht, in den Arbeitsspeicherblock zu lesen oder zu schreiben, den das System der Variable zuweist. Wenn der Watchpoint entweder bei einem Lese- oder Schreibvorgang ausgelöst werden soll, wählen Sie Beliebig aus.
  4. Klicke auf Fertig.

Klicken Sie im Fehlerbehebungsfenster auf Haltepunkte ansehen , um alle Watchpoints anzusehen und Watchpoint-Einstellungen zu konfigurieren. Das Dialogfeld „Breakpoints“ wird angezeigt (siehe Abbildung 10).

Abbildung 10. Im Dialogfeld „Breakpoints“ werden Ihre aktuellen Watchpoints und deren Verhaltenseinstellungen aufgelistet.

Nachdem Sie den Watchpoint hinzugefügt haben, klicken Sie im Fenster zur Fehlerbehebung auf Programm fortsetzen , um den Anwendungsprozess fortzusetzen. Wenn Ihre App versucht, auf einen Speicherblock zuzugreifen, für den Sie einen Watchpoint eingerichtet haben, hält das Android-System den App-Prozess an und neben der Codezeile, die Ihre App zuletzt ausgeführt hat, wird ein Watchpoint-Symbol angezeigt (siehe Abbildung 11).

Abbildung 11. In Android Studio wird die Codezeile angegeben, die deine App unmittelbar vor dem Auslösen eines Watchpoint ausführt.

Anzeigeformat für Ressourcenwerte ansehen und ändern

Im Debug-Modus können Sie Ressourcenwerte ansehen und ein anderes Anzeigeformat für Variablen in Ihrem Java- oder Kotlin-Code auswählen. Wenn der Tab „Variablen“ angezeigt und ein Frame ausgewählt ist, gehen Sie so vor:

  1. Klicken Sie in der Variablenliste mit der rechten Maustaste auf eine beliebige Stelle in einer Ressourcenzeile, um die Liste aufzurufen.
  2. Wählen Sie in der Liste Anzeigen als und dann das gewünschte Format aus.

    Die verfügbaren Formate hängen vom Datentyp der ausgewählten Ressource ab. Möglicherweise wird eine oder mehrere der folgenden Optionen angezeigt:

    • Klasse:Zeigt die Klassendefinition an.
    • toString:Anzeigestringformat.
    • Objekt:Zeigt die Objektdefinition (Instanz einer Klasse) an.
    • Array:Anzeige in einem Array-Format
    • Zeitstempel:Zeigen Sie Datum und Uhrzeit so an: jjjj-mm-tt hh:mm:ss.
    • Automatisch:Android Studio wählt basierend auf dem Datentyp das beste Format aus.
    • Binär:Zeigt einen Binärwert mit Nullen und Einsen an.
    • MeasureSpec:Wert, der vom übergeordneten Element an das ausgewählte untergeordnete Element übergeben wird Weitere Informationen finden Sie unter MeasureSpec.
    • Hexadezimal:Wird als Hexadezimalwert angezeigt.
    • Einfach:Die Anzeige wird als numerischer Wert mit einem primitiven Datentyp angezeigt.
    • Ganzzahl: Wird als numerischer Wert vom Typ Integer angezeigt.

So erstellen Sie ein benutzerdefiniertes Format:

  1. Klicken Sie mit der rechten Maustaste auf den Ressourcenwert.
  2. Wählen Sie Ansehen als aus.
  3. Wählen Sie Erstellen aus.
  4. Das Dialogfeld Java-Datentyp-Renderer wird angezeigt. Folgen Sie der Anleitung unter Renderer für Java-Datentypen.