App-Fehler beheben

Android Studio bietet einen Debugger, mit dem Sie unter anderem Folgendes tun können:

  • Wähle ein Gerät aus, auf dem du deine App debuggen möchtest.
  • Setzen Sie Haltepunkte in Ihrem Java-, Kotlin- und C/C++-Code.
  • Variablen untersuchen und Ausdrücke zur Laufzeit auswerten

Diese Seite enthält Anweisungen für grundlegende Debugger-Vorgänge. Weitere Informationen finden Sie auch in den Fehlerbehebungsdokumenten von IntelliJ IDEA.

Fehlerbehebung aktivieren

Bevor Sie mit dem Debugging beginnen können, müssen Sie Folgendes tun:

Aktiviere die Fehlerbehebung auf deinem Gerät.
Wenn Sie den Emulator verwenden, ist die Fehlerbehebung standardmäßig aktiviert. Bei einem verbundenen Gerät musst du jedoch das Debugging in den Optionen für Geräteentwickler aktivieren.
Führen Sie eine Debug-fähige Build-Variante aus.

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

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

Cool

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

Kotlin

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

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

Hinweis:Das Attribut jniDebuggable wird nicht mehr verwendet.

Wenn Ihre Anwendung von einem Bibliotheksmodul abhängt, das Sie ebenfalls debuggen möchten, muss diese Bibliothek auch mit debuggable true gepackt sein, damit die Fehlerbehebungssymbole erhalten bleiben. Damit die Debug-fähigen Varianten Ihres App-Projekts die debug-fähige Variante eines Bibliotheksmoduls erhalten, sollten Sie nicht standardmäßige Versionen Ihrer Bibliothek veröffentlichen.

Fehlerbehebung starten

So starten Sie eine Debugging-Sitzung:

  1. Haltepunkte im Code Ihrer App festlegen
  2. Wählen Sie in der Symbolleiste im Zielgerätemenü das Gerät aus, auf dem Sie Ihre App debuggen möchten.
    Menü des Zielgeräts.
    Abbildung 1. Menü des Zielgeräts.

    Wenn du keine Geräte konfiguriert hast, musst du entweder ein Gerät über USB anschließen, 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 Ihre App bereits auf dem Gerät ausgeführt wird, werden Sie in einem Dialogfeld gefragt, ob Sie von „Ausführen“ zur Fehlerbehebung wechseln möchten. Das Gerät muss neu gestartet werden, um mit der Fehlerbehebung zu beginnen. Klicken Sie auf Fehlerbehebung abbrechen und hängen Sie den Debugger stattdessen an eine laufende App an, damit dieselbe Instanz der App weiterhin 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 Fenster „Fehlerbehebung“ auch den LLDB-Debugger aus, um den nativen Code zu debuggen.

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

Debugger an laufende Anwendung anhängen

Wenn deine App bereits auf deinem Gerät ausgeführt wird, kannst du mit der Fehlerbehebung beginnen, ohne die App neu starten zu müssen. Gehe 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 Sie einen Emulator oder ein gerootetes Gerät verwenden, können Sie 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 hier jedoch nur Debug-fähige Prozesse angezeigt.
    2. Im Menü Android Debugger-Einstellungen verwenden aus können Sie eine vorhandene Ausführungs-/Fehlerbehebungskonfiguration auswählen. So können Sie für C- und C++-Code die LLDB-Startbefehle, LLDB-Post-attach-Befehle und Symbolverzeichnisse in einer vorhandenen Konfiguration wiederverwenden.
    3. Wenn noch keine Ausführungs-/Fehlerbehebungskonfiguration vorhanden ist, 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 für Sie am besten geeignete Debugger-Option auszuwählen, je nachdem, ob Ihr Projekt Java- oder C/C++-Code enthält.
  3. Klicke auf OK.

    Das Fenster zur Fehlerbehebung wird angezeigt.

Auf dem Tab Prozesse im Geräte-Explorer (Ansicht > Tool-Fenster > Geräte-Explorer) finden Sie ebenfalls eine Liste mit Debug-fähigen Prozessen. Dort können Sie einen Prozess auswählen und beenden, das Beenden erzwingen oder den Debugger an einen bestimmten Prozess anhängen.

Debugging-Fenster

Abbildung 2: Das Debugging-Fenster

Das Debug-Fenster ist in

  1. Ausführungs- und Navigationssymbolleiste, siehe Mit Haltepunkten arbeiten
  2. Thread-Auswahl
  3. Bewertungs- und Überwachungsausdruck. 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 stellt sicher, dass jedes Objekt, das der Debugger erkennt, erst bereinigt wird, nachdem die Verbindung zum Debugger getrennt wurde. Dies kann zu einer Ansammlung von Objekten führen, 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 der Debugger getrennt wird, selbst wenn der Thread beendet wurde.

Debugger-Typ ändern

Da zum Debuggen von Java-/Kotlin-Code und C/C++-Code verschiedene Debugger-Tools erforderlich sind, können Sie im Android Studio-Debugger den zu verwendenden Debugger-Typ auswählen. Standardmäßig entscheidet Android Studio mithilfe des Debugger-Typs Automatisch erkennen, welcher Debugger verwendet wird, je nachdem, welche Sprachen im Projekt erkannt werden.

Wenn Sie den Debugger manuell in der Fehlerbehebungskonfiguration auswählen möchten, 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 Fehlerbehebungstyp 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 Debug-Typ „Dual“. Andernfalls verwendet Android Studio den Debug-Typ „Nur Java“.
Nur Java
Wählen Sie diesen Fehlerbehebungstyp aus, wenn Sie nur Code debuggen möchten, der in Java oder Kotlin geschrieben wurde. Der Java-Only-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 Debug-Typ aus, wenn Sie zur Fehlerbehebung nur LLDB verwenden möchten. Bei Verwendung dieses Fehlerbehebungstyps ist die Sitzungsansicht für den Java-Debugger nicht verfügbar. Standardmäßig prüft LLDB nur den nativen Code und ignoriert Haltepunkte im Java-Code. Wenn Sie auch Ihren Java-Code debuggen möchten, wechseln Sie entweder zum Debug-Typ „Automatisch erkennen“ oder „Dual“.

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.

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

    sysctl kernel.yama.ptrace_scope
    

    Wenn ptrace aktiviert ist, gibt der Befehl den Wert 0 oder den Fehler unknown key 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 Fehlerbehebungstyp aus, wenn Sie zwischen der Fehlerbehebung für Java und nativen Code wechseln möchten. Android Studio hängt sowohl den Java-Debugger als auch LLDB an deinen App-Prozess an, sodass du Haltepunkte sowohl im Java- als auch im nativen Code prüfen kannst, ohne deine App neu starten oder die Debug-Konfiguration ändern zu müssen.

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 zur Fehlerbehebung im nativen Code 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 wird, wird möglicherweise die folgende Warnmeldung angezeigt:
This function was compiled with optimizations enabled. Some debugger features may not be available. Bei Verwendung von Optimierungs-Flags nimmt der Compiler Änderungen am 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 den Debugger schwierig ist, den optimierten kompilierten Code wieder dem ursprünglichen Quellcode zuzuordnen. Aus diesem Grund sollten Sie Compiler-Optimierungen beim Debuggen des nativen Codes deaktivieren.

Systemprotokoll verwenden

Im Systemlog werden Systemmeldungen angezeigt, während Sie Fehler in Ihrer App beheben. Diese Meldungen enthalten Informationen von Apps, die auf dem Gerät ausgeführt werden. Wenn Sie das Systemlog zur Fehlerbehebung Ihrer Anwendung verwenden möchten, achten Sie darauf, dass Ihr Code Lognachrichten schreibt und den Stacktrace für Ausnahmen ausgibt, während sich Ihre App in der Entwicklungsphase befindet.

Logeinträge in Ihren Code schreiben

Verwenden Sie die Klasse Log, um Logeinträge in Ihren Code zu schreiben. Logmeldungen helfen Ihnen, den Ausführungsfluss nachzuvollziehen. Sie erfassen die Debug-Ausgabe des Systems, während Sie mit Ihrer Anwendung interagieren. Sie können auch Aufschluss darüber geben, welcher Teil Ihrer App fehlgeschlagen ist. Weitere Informationen zum Logging finden Sie unter Logs mit Logcat schreiben und ansehen.

Das folgende Beispiel zeigt, wie Sie Logeinträge hinzufügen können, um festzustellen, ob Informationen zum vorherigen Status zu Beginn Ihrer Aktivität 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 Fehlerbehebungs-Logmeldungen und Stacktrace-Druckaufrufe aus Ihrem Code, sobald Sie Ihre App veröffentlichen möchten. Legen Sie dazu das Flag DEBUG fest und platzieren Sie Fehlerbehebungs-Logmeldungen in bedingten Anweisungen.

Systemprotokoll aufrufen

Sie können Debug- und andere Systemmeldungen im Logcat-Fenster ansehen und filtern, wie in Abbildung 4 gezeigt. Beispielsweise können Sie Nachrichten sehen, wenn die automatische Speicherbereinigung stattfindet, oder Nachrichten, die Sie Ihrer Anwendung mit der Klasse Log hinzufügen.

Wenn Sie Logcat verwenden möchten, beginnen Sie mit der Fehlerbehebung und wählen Sie den Tab „Logcat“ aus.

Abbildung 4: Logcat-Fenster mit Filtereinstellungen

Eine Beschreibung von Logcat und seiner 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 häufigste Typ ist ein Haltepunkt in einer Zeile, der die Ausführung der App bei einer bestimmten Codezeile pausiert. Während der Pausierung können Sie Variablen überprüfen, Ausdrücke auswerten und 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 App, wenn eine bestimmte Methode gestartet oder beendet wird. Während der Pausierung können Sie Variablen überprüfen, Ausdrücke auswerten und 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, listet der Debugger die Parameter der zusammensetzbaren Funktion und ihren Status auf, um festzustellen, welche Änderungen zur Neuzusammensetzung geführt haben könnten.
Haltepunkt für Feld
Ein Feldhaltepunkt pausiert die Ausführung der Anwendung, wenn sie aus einem bestimmten Feld liest oder in ein bestimmtes Feld schreibt.
Ausnahmehaltepunkt
Ein Ausnahmehaltepunkt pausiert die Ausführung deiner App, wenn eine Ausnahme ausgelöst wird.

Sie können bedingte Haltepunkte festlegen, die die Ausführung nur unterbrechen, wenn bestimmte Bedingungen erfüllt sind. Sie können auch Haltepunkte für das Logging festlegen, die in Logcat schreiben, ohne die Ausführung anzuhalten. So können Sie vermeiden, dass Ihr Code mit Loganweisungen ü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 Bundsteg 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 Fehler beheben , um mit der Fehlerbehebung zu beginnen.

Wenn Sie einen Haltepunkt festlegen, wird neben der Zeile ein roter Punkt angezeigt (siehe Abbildung 5).

Abbildung 5. Wenn Sie einen Haltepunkt festlegen, wird neben der Zeile ein roter Punkt angezeigt.

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

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

  • Um die Objektstruktur nach einer Variablen zu suchen, erweitern Sie sie in der Ansicht „Variablen“. Wenn die Variablenansicht nicht angezeigt wird, klicken Sie auf Layouteinstellungen und prüfen Sie, ob Variablen aktiviert sind.

  • Um zur nächsten Zeile im Code zu springen, ohne eine Methode einzugeben, klicken Sie auf Step Over .

  • Wenn Sie innerhalb eines Methodenaufrufs zur ersten Zeile wechseln möchten, klicken Sie auf Step Into .

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

  • Klicken Sie auf Programm fortsetzen , um die App weiter wie gewohnt auszuführen.

Wenn Ihr Projekt nativen Code verwendet, werden durch den Fehlerbehebungstyp „Automatisch erkennen“ standardmäßig sowohl der Java-Debugger als auch LLDB als zwei separate Prozesse an Ihre Anwendung angehängt. Sie können zwischen der Prüfung von Java- und C/C++ Haltepunkten 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 Debug-Typ ändern, der in Android Studio verwendet wird, indem Sie die Fehlerbehebungskonfiguration bearbeiten. Weitere Informationen zu den verschiedenen Fehlerbehebungstypen finden Sie im Abschnitt zur Verwendung anderer Fehlerbehebungstypen.

Wenn Android Studio deine App auf dem Zielgerät bereitstellt, öffnet sich das Fenster zur Fehlerbehebung mit einem Tab oder einer Ansicht der Debug-Sitzung für jeden Debugger-Prozess, wie in Abbildung 6 dargestellt.

Abbildung 6. Fehlerbehebung bei nativem Code mit LLDB.
  1. Android Studio wechselt zum Tab <your-module>, wenn der LLDB-Debugger einen Haltepunkt im C/C++-Code erkennt. Die Bereiche „Frames“, „Variables“ und „Watches“ sind ebenfalls verfügbar und funktionieren genau so, wie sie beim Debugging von Java-Code funktionieren würden.

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

    Hinweis:Während der Überprü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 nicht mit dem Java-Debugger interagieren oder Statusinformationen aus Ihrer Java-Debugger-Sitzung abrufen können, während Sie einen Haltepunkt in Ihrem nativen Code überprüfen.

  2. Android Studio wechselt zum Java-Tab <your-module>, wenn der Java-Debugger im Java- oder Kotlin-Code auf einen Haltepunkt stößt.
  3. Bei der Fehlerbehebung mit LLDB können Sie das LLDB-Terminal in der LLDB-Sitzungsansicht verwenden, um Befehlszeilenoptionen an LLDB zu übergeben. Wenn Sie bestimmte Befehle haben, die LLDB bei jedem Start der Fehlerbehebung für Ihre Anwendung ausführen soll, entweder kurz vor oder kurz nachdem der Debugger an Ihren Anwendungsprozess angehängt wurde, 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 Ihren Anwendungsprozess anhalten, wenn Ihre Anwendung mit einem bestimmten Speicherblock interagiert. Weitere Informationen findest du im Abschnitt zum Hinzufügen von Watchpoints.

Haltepunkte ansehen und konfigurieren

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

Abbildung 7. Im Fenster „Breakpoints“ werden alle aktuellen Haltepunkte und die jeweiligen Verhaltenseinstellungen aufgelistet.

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 deine App nicht, wenn dieser Haltepunkt erreicht wird.

Wählen Sie einen Haltepunkt aus der Liste aus, um dessen Einstellungen zu konfigurieren. Sie können einen Haltepunkt so konfigurieren, dass er zuerst deaktiviert wird, und ihn vom System nach einem anderen Haltepunkt aktivieren lassen. Sie können auch konfigurieren, ob ein Haltepunkt nach einem Treffer deaktiviert werden soll. Um einen Haltepunkt für eine Ausnahme festzulegen, wählen Sie in der Liste der Haltepunkte Ausnahmehaltepunkte aus.

Klicken Sie im Fenster zur Fehlerbehebung auf Haltepunkte ausblenden , um alle Haltepunkte vorübergehend zu deaktivieren. Klicken Sie noch einmal, um sie wieder zu aktivieren.

Debugging-Fensterrahmen

Im Debugger-Fenster können Sie im Bereich „Frames“ den Stapelframe untersuchen, der zum Treffer des aktuellen Haltepunkts geführt hat. Auf diese Weise können Sie den Stapelframe aufrufen und untersuchen sowie die Liste der Threads in Ihrer Android-App prüfen.

Verwenden Sie das Thread-Auswahlmenü und sehen Sie sich den Stapelframe an, um einen Thread auszuwählen. Klicken Sie auf die Elemente im Frame, um den Quelltext im Editor zu öffnen. Sie können auch die Darstellung des Threads anpassen und den Stapelframe exportieren, wie im Leitfaden zum Prüfen von Frames beschrieben.

Variablen prüfen

Im Debugger-Fenster können Sie im Bereich „Variablen“ Variablen prüfen, wenn das System Ihre App an einem Haltepunkt anhält und Sie einen Frame aus dem Bereich „Frames“ 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 läuft:

Abbildung 8: Objektstruktur und Ausdruckseingabefeld im Debugging-Fenster
  1. Zu beobachtenden oder anzuzeigenden Ausdruck eingeben
  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 auch 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 durchlaufen.

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

Um einen beobachteten Ausdruck aus der Objektstruktur zu entfernen, klicken Sie mit der rechten Maustaste auf den Ausdruck und dann auf Beobachtungsliste entfernen.

Watchpoints hinzufügen

Beim Debuggen von C/C++ Code können Sie spezielle Arten von Haltepunkten festlegen, sogenannte Watchpoints. Diese können Ihren Anwendungsprozess anhalten, wenn Ihre Anwendung mit einem bestimmten Speicherblock interagiert. Wenn Sie beispielsweise zwei Zeiger auf einen Speicherblock setzen und ihm einen Watchpoint zuweisen, wird der Watchpoint ausgelöst, wenn Sie einen der Zeiger für den Zugriff auf diesen Block verwenden.

In Android Studio können Sie einen Watchpoint während der Laufzeit 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 Variable selbst. Dies unterscheidet sich vom Hinzufügen einer Variablen zum Bereich „Watches“, mit dem Sie den Wert einer Variablen beobachten können, aber nicht Ihren Anwendungsprozess anhalten können, wenn das System ihren Wert im Arbeitsspeicher liest oder ändert.

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

Sie müssen die folgenden Anforderungen erfüllen, um einen Watchpoint einzurichten:

  • Ihr physisches Zielgerät oder 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 für 32-Bit-Prozessoren oder auf 8 Byte für 64-Bit-Prozessoren ausrichten. Wenn Sie eine Variable in Ihrem nativen Code ausrichten möchten, geben Sie __attribute__((aligned(num_bytes))) in der Variablen deceleration an, wie unten gezeigt:
    // 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, kann es zu einem Absturz kommen, wenn Sie einen Watchpoint hinzufügen oder den Mauszeiger auf Variablen innerhalb des Codes bewegen, um deren Werte zu untersuchen. Als Behelfslösung können Sie das Debugging mit 64-Bit-ARM-, x86- oder x86_64-Binärdateien durchführen. Dieses Problem wird in einer künftigen Version von Android Studio behoben.

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

  1. Öffnen Sie in der Ansicht der LLDB-Sitzung den Bereich „Variablen“, während Ihre App an einem Haltepunkt gesperrt ist.
  2. Klicken Sie mit der rechten Maustaste auf eine Variable, die den zu verfolgenden Arbeitsspeicherblock belegt, und wählen Sie Watchpoint hinzufügen aus.

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

    Konfigurieren Sie Ihren Watchpoint mit den folgenden Optionen:

    • Aktiviert:Deaktiviere diese Option, wenn du Android Studio anweisen möchtest, den Watchpoint zu ignorieren, bis du die Einstellung änderst. Android Studio speichert Ihren Watchpoint, damit Sie später darauf zugreifen können.
    • Anhalten:Standardmäßig hält das Android-System Ihren App-Prozess an, wenn es auf einen Speicherblock zugreift, den Sie einem Watchpoint zuweisen. Deaktivieren Sie diese Option, wenn Sie das nicht möchten. Dadurch werden zusätzliche Optionen angezeigt, mit denen Sie das Verhalten bei der Interaktion des Systems mit Ihrem Watchpoint anpassen können: Nachricht in Konsole protokollieren und Bei Treffer entfernen.
    • Zugriffstyp:Wählen Sie aus, ob die Anwendung den Watchpoint auslösen soll, wenn sie versucht, den Arbeitsspeicherblock zu lesen, den das System der Variablen zuweist, Lesen oder Schreiben. Wählen Sie Beliebig aus, um den Watchpoint bei einem Lese- oder Schreibvorgang auszulösen.
  4. Klicke auf Fertig.

Wenn Sie alle Watchpoints aufrufen und die Watchpoint-Einstellungen konfigurieren möchten, klicken Sie im Debugging-Fenster auf Haltepunkte ansehen . Das Dialogfeld "Haltepunkte" wird angezeigt (siehe Abbildung 10).

Abbildung 10. Das Dialogfeld „Breakpoints“ enthält Ihre aktuellen Watchpoints und die Verhaltenseinstellungen für jeden einzelnen.

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

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

Anzeigeformat für Ressourcenwerte ansehen und ändern

Im Debug-Modus können Sie sich 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. Eine oder mehrere der folgenden Optionen werden angezeigt:

    • Klasse:Die Klassendefinition wird angezeigt.
    • toString:Das Format des Strings wird angezeigt.
    • Objekt:Die Definition des Objekts (eine Instanz einer Klasse) anzeigen.
    • Array:Wird in einem Arrayformat angezeigt.
    • Zeitstempel:Geben Sie Datum und Uhrzeit wie folgt an: jjjj-mm-tt hh:mm:ss.
    • Auto:In Android Studio wird basierend auf dem Datentyp das beste Format ausgewählt.
    • Binär: Zeigt einen Binärwert mit Nullen und Einsen an.
    • MeasureSpec:Der Wert, der vom übergeordneten Element an das ausgewählte untergeordnete Element übergeben wird. Weitere Informationen finden Sie unter MeasureSpec.
    • Hexadezimal:Wird als Hexadezimalwert angezeigt.
    • Primitiv: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.