Anwendung debuggen

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

  • Wählen Sie ein Gerät aus, auf dem Sie Ihre App debuggen möchten.
  • Setzen Sie Haltepunkte in Ihrem Java-, Kotlin- und C/C++-Code.
  • Variablen prüfen und Ausdrücke zur Laufzeit auswerten

Auf dieser Seite finden Sie eine Anleitung für grundlegende Debugger-Vorgänge. Weitere Informationen finden Sie in der IntelliJ IDEA-Dokumentation zum Debuggen.

Debug aktivieren

Bevor Sie mit der Fehlerbehebung 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 eine Buildvariante, die debuggable true (isDebuggable = true in Kotlin-Scripts) in der Build-Konfiguration enthält.

Normalerweise können Sie die Standardvariante „debug“ auswählen, die in jedem Android Studio-Projekt enthalten ist, auch wenn sie in der build.gradle-Datei nicht 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 Sitzung zur Fehlerbehebung:

  1. Legen Sie Haltepunkte im Code Ihrer App fest.
  2. Wählen Sie in der Symbolleiste im Menü „Zielgerät“ ein Gerät aus, auf dem Sie Ihre App debuggen möchten.
    Menü des Zielgeräts.
    Abbildung 1: Menü „Zielgerät“.

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

  3. Klicken Sie in der Symbolleiste auf Fehler beheben .

    Wenn Ihre App bereits auf dem Gerät ausgeführt wird, wird ein Dialogfeld angezeigt, in dem Sie gefragt werden, ob Sie von „Ausführen“ zu „Debuggen“ wechseln möchten. Das Gerät muss neu gestartet werden, um mit der Fehlerbehebung zu beginnen. Wenn Sie dieselbe Instanz der App weiterhin ausführen möchten, klicken Sie auf Debugging abbrechen und verknüpfen Sie den Debugger stattdessen mit einer laufenden App. Andernfalls erstellt Android Studio ein APK, signiert es mit einem Debug-Schlüssel, 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. Wenn das Debugfenster nicht geöffnet ist, wählen Sie Ansicht > Toolfenster > Debug aus oder klicken Sie in der Toolfensterleiste auf Debug .

Debugger an eine laufende App anhängen

Wenn Ihre App bereits auf Ihrem Gerät ausgeführt wird, können Sie das Debuggen starten, 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, dem Sie den Debugger zuordnen möchten.
    1. Wenn Sie einen Emulator oder ein gerootetes Gerät verwenden, können Sie das Kästchen Alle Prozesse anzeigen anklicken, um alle Prozesse zu sehen. Auf einem gerooteten Gerät werden alle Prozesse angezeigt, die auf dem Gerät ausgeführt werden. Auf einem nicht gerooteten Gerät werden jedoch nur debuggbare Prozesse angezeigt.
    2. Wählen Sie im Menü Android-Debuggereinstellungen verwenden von eine vorhandene Ausführungs-/Debug-Konfiguration aus. Bei C- und C++-Code können Sie so die LLDB-Startbefehle, LLDB-Befehle nach dem Anhängen und Symbolverzeichnisse in einer vorhandenen Konfiguration wiederverwenden.
    3. Wenn Sie noch keine Ausführungs-/Debug-Konfiguration haben, wählen Sie Neu erstellen aus. Dadurch wird das Menü Debug-Typ aktiviert, in dem Sie einen anderen Debug-Typ 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. Klicken Sie 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 ihn beenden (), zum Beenden zwingen () oder den Debugger an einen bestimmten Prozess anhängen ().

Debugging-Fenster

Abbildung 2: Das Debugging-Fenster

Das Debug-Fenster ist in folgende Bereiche unterteilt:

  1. Symbolleiste für Ausführung und Navigation Mit Haltepunkten arbeiten
  2. Thread-Auswahl
  3. Auswertungs- und Überwachungsausdruck. Weitere Informationen finden Sie unter Variablen prüfen.
  4. Stapelanzeige
  5. Variablen. Weitere Informationen finden Sie unter Variablen prüfen.

Hinweis:Der Android Studio-Debugger und der Garbage Collector sind nur lose miteinander verbunden. Die Android-virtuelle Maschine sorgt dafür, dass Objekte, die dem Debugger bekannt sind, erst nach der Trennung des Debuggers vom Debug-Objekt durch die Garbage Collection entfernt werden. 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 unterschiedliche Debugger-Tools erforderlich sind, können Sie im Android Studio-Debugger auswählen, welchen Debugger-Typ Sie verwenden möchten. Standardmäßig entscheidet Android Studio anhand der in Ihrem Projekt erkannten Sprachen, welcher Debugger verwendet werden soll. Dazu wird der Debuggertyp Automatisch erkennen verwendet.

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 im Dialogfeld auswählen, das angezeigt wird, wenn Sie auf Ausführen > Debugger an Android-Prozess anhängen klicken.

Folgende Debug-Typen sind verfügbar:

Automatisch erkennen
Wählen Sie diesen Debugtyp aus, wenn Android Studio automatisch die beste Option für den zu behebenden Code auswählen soll. Wenn Ihr Projekt beispielsweise C- oder C++-Code enthält, verwendet Android Studio automatisch den Debug-Typ „Dual“. Andernfalls verwendet Android Studio den Debugging-Typ „Nur Java“.
Nur Java
Wählen Sie diesen Debugging-Typ aus, wenn Sie nur Code debuggen möchten, der in Java oder Kotlin geschrieben wurde. Der 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 Debug-Typ aus, wenn Sie zur Fehlerbehebung nur das LLDB-Tool verwenden möchten. Bei Verwendung dieses Fehlerbehebungstyps ist die Sitzungsansicht für den Java-Debugger nicht verfügbar. Standardmäßig prüft LLDB nur Ihren nativen Code und ignoriert Haltestellen im Java-Code. Wenn Sie auch Ihren Java-Code debuggen möchten, wechseln Sie entweder zu „Automatisch erkennen“ oder „Duales Debuggen“.

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 + Native) – 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 koppelt sowohl den Java-Debugger als auch LLDB an Ihren App-Prozess, sodass Sie sowohl Java- als auch nativen Code untersuchen können, ohne die 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 App sowohl Java- als auch C++-Code enthält, dient ein Tab zum Debuggen des nativen Codes und der andere zum Debuggen von Java-Code, wie durch -java angegeben.

Abbildung 3: Tab zum Debuggen von nativem Code und Tab zum Debuggen von Java-Code

Hinweis:Beim Debuggen von nativem Code, der vom Compiler optimiert wird, wird möglicherweise die folgende Warnung 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 ausführen zu können. 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 Compileroptimierungen beim Debuggen Ihres nativen Codes deaktivieren.

Systemprotokoll verwenden

Das Systemprotokoll enthält Systemmeldungen, während Sie Ihre App debuggen. Diese Meldungen enthalten Informationen von Apps, die auf dem Gerät ausgeführt werden. Wenn Sie das Systemprotokoll zum Debuggen Ihrer App verwenden möchten, achten Sie darauf, dass Ihr Code während der Entwicklungsphase Lognachrichten schreibt und den Stack-Trace für Ausnahmen druckt.

Lognachrichten in den Code schreiben

Verwenden Sie die Klasse Log, um Protokollnachrichten in Ihren Code einzufügen. Logmeldungen helfen Ihnen, den Ablauf der Ausführung zu verstehen, indem die System-Debugausgabe erfasst wird, während Sie mit Ihrer App interagieren. Logmeldungen können Ihnen auch Aufschluss darüber geben, welcher Teil Ihrer App fehlgeschlagen ist. Weitere Informationen zum Logging finden Sie unter Logs mit Logcat schreiben und ansehen.

Im folgenden Beispiel wird gezeigt, wie Sie Protokollmeldungen hinzufügen können, um zu ermitteln, ob Informationen zum vorherigen Status verfügbar sind, wenn Ihre Aktivität beginnt:

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 Systemprotokoll 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-Lognachrichten und Stack-Trace-Druckaufrufe aus Ihrem Code, wenn Sie Ihre App veröffentlichen möchten. Legen Sie dazu ein DEBUG-Flag fest und platzieren Sie Debug-Lognachrichten in bedingten Anweisungen.

Systemprotokoll aufrufen

Sie können im Logcat-Fenster Debug- und andere Systemmeldungen aufrufen und filtern, wie in Abbildung 4 dargestellt. Sie können sich beispielsweise Nachrichten anzeigen lassen, wenn die Garbage Collection ausgeführt wird, oder Nachrichten, die Sie Ihrer App mit der Klasse Log hinzufügen.

Wenn Sie Logcat verwenden möchten, starten Sie das Debuggen 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 aufrufen.

Mit Haltepunkten arbeiten

Android Studio unterstützt Haltestellen, die verschiedene Debug-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 Ausführungspause können Sie Variablen prüfen, Ausdrücke auswerten und die Ausführung dann zeilenweise fortsetzen, um die Ursachen von Laufzeitfehlern zu ermitteln.
Methoden-Haltepunkt
Mit einem Methoden-Bruchpunkt wird die Ausführung Ihrer App angehalten, wenn eine bestimmte Methode aufgerufen oder verlassen wird. Während der Ausführungspause können Sie Variablen prüfen, Ausdrücke auswerten und die Ausführung dann zeilenweise fortsetzen, um die Ursachen von Laufzeitfehlern zu ermitteln. Wenn Sie einen Haltepunkt in einer zusammensetzbaren Funktion setzen, listet der Debugger die Parameter der zusammensetzbaren Funktion und ihren Status auf, um zu ermitteln, welche Änderungen die Neuzusammensetzung verursacht haben könnten.
Feld-Haltepunkt
Mit einem Feld-Bruchpunkt wird die Ausführung Ihrer App pausiert, wenn aus einem bestimmten Feld gelesen oder in ein bestimmtes Feld geschrieben wird.
Ausnahme-Haltepunkt
Mit einem Ausnahme-Haltepunkt wird die Ausführung Ihrer App angehalten, wenn eine Ausnahme ausgelöst wird.

Sie können bedingte Haltestellen festlegen, die die Ausführung nur dann pausieren, wenn bestimmte Bedingungen erfüllt sind. Sie können auch Logging-Bruchstellen festlegen, die in Logcat schreiben, ohne die Ausführung anzuhalten. So können Sie Ihren Code nicht mit Protokollanweisungen überladen.

So fügen Sie einen Zeilen-Bruchpunkt hinzu:

  1. Suchen Sie die Codezeile, an der Sie die Ausführung pausieren möchten.
  2. Klicken Sie auf den linken Rand dieser Codezeile oder setzen Sie den Cursor in die 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 setzen, 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 App zu ermitteln:

  • Wenn Sie den Objektbaum für eine Variable untersuchen möchten, maximieren Sie sie in der Ansicht „Variablen“. Wenn die Ansicht „Variablen“ nicht angezeigt wird, klicken Sie auf Layouteinstellungen und achten Sie darauf, dass Variablen aktiviert ist.

  • Wenn Sie zur nächsten Zeile im Code springen möchten, ohne eine Methode einzugeben, klicken Sie auf Überspringen .

  • Wenn Sie zur ersten Zeile in einem Methodenaufruf springen möchten, klicken Sie auf Einblenden .

  • Wenn Sie zur nächsten Zeile außerhalb der aktuellen Methode wechseln möchten, klicken Sie auf Aus Schritt .

  • Wenn Sie die App wie gewohnt ausführen möchten, klicken Sie auf Programm fortsetzen .

Wenn in Ihrem Projekt nativer Code verwendet wird, werden beim Debug-Typ „Automatisch erkennen“ standardmäßig sowohl der Java-Debugger als auch LLDB als zwei separate Prozesse an Ihre App angehängt. Sie können zwischen der Prüfung von Java- und C/C++-Bruchpunkten wechseln, ohne die App neu zu starten oder die Einstellungen zu ändern.

Hinweis:Damit Android Studio Haltestellen in Ihrem C- oder C++-Code erkennt, müssen Sie einen Debugtyp verwenden, der LLDB unterstützt, z. B. „Automatisch erkennen“, „Native“ oder „Dual“. Sie können den in Android Studio verwendeten Debug-Typ ändern, indem Sie Ihre Debug-Konfiguration 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 Debugging-Fenster mit einem Tab oder einer Ansicht der Debug-Sitzung für jeden Debugger-Prozess, wie in Abbildung 6 dargestellt.

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

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

    Hinweis:Wenn Sie einen Haltepunkt in Ihrem nativen Code prüfen, hält das Android-System die virtuelle Maschine an, auf der der Java-Bytecode Ihrer App 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 prüfen.

  2. Android Studio wechselt zum Tab <your-module>-java, wenn der Java-Debugger einen Haltepunkt in Ihrem Java- oder Kotlin-Code findet.
  3. Während der Fehlerbehebung mit LLDB können Sie über das LLDB-Terminal in der LLDB-Sitzungsansicht Befehlszeilenoptionen an LLDB übergeben. Wenn Sie bestimmte Befehle haben, die das LLDB jedes Mal ausführen soll, wenn Sie mit der Fehlerbehebung in Ihrer Anwendung beginnen, 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

Wenn Sie alle Haltepunkte aufrufen und die Einstellungen für Haltepunkte konfigurieren möchten, klicken Sie im Debugfenster auf Haltepunkte ansehen . Das Fenster "Haltepunkte" wird angezeigt, wie in Abbildung 7 dargestellt.

Abbildung 7: Im Fenster „Breakpoints“ werden alle aktuellen Haltestellen aufgelistet und es enthält Verhaltenseinstellungen für jede.

Im Fenster „Bruchstellen“ können Sie jeden Bruchpunkt 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 bestimmten Breakpoint so konfigurieren, dass er zuerst deaktiviert wird und erst dann vom System aktiviert wird, wenn ein anderer Breakpoint erreicht wird. Sie können auch konfigurieren, ob ein Haltepunkt deaktiviert werden soll, nachdem er erreicht wurde. 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 die Funktion wieder zu aktivieren.

Debugging-Fensterrahmen

Im Debugger-Fenster können Sie im Bereich „Frames“ den Stackframe prüfen, der dazu geführt hat, dass der aktuelle Haltepunkt erreicht wurde. So können Sie den Stack Frame aufrufen und prüfen sowie die Liste der Threads in Ihrer Android-App untersuchen.

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 die Darstellung des Threads auch anpassen und den Stack-Frame 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 beendet und Sie im Bereich „Frames“ einen Frame auswählen. Im Bereich „Variablen“ können Sie auch Ad-hoc-Ausdrücke mithilfe von statischen Methoden und/oder Variablen auswerten, die im ausgewählten Frame verfügbar sind.

So fügen Sie der Objektstruktur einen Ausdruck hinzu, während die Anwendung debuggt wird:

Abbildung 8 Objektstruktur und Ausdruckseingabefeld im Debugging-Fenster
  1. Ausdruck eingeben, der beobachtet oder angezeigt werden soll
  2. Klicken Sie auf Zu Beobachtungen hinzufügen oder drücken Sie die Eingabetaste, um den Ausdruck einmal zu berechnen.

Wenn der Objektbaum den Ausdruck enthält, den Sie beobachten möchten, können Sie ihn auch an den Anfang des Baums ziehen, um ihn als beobachteten Ausdruck hinzuzufügen.

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

Ausgewertete Ausdrücke bleiben oben im Objektbaum angezeigt, bis Sie einen anderen Ausdruck manuell auswerten oder den Code durchgehen.

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

Watchpoints hinzufügen

Beim Debuggen von C/C++-Code können Sie spezielle Arten von Haltepunkten festlegen, sogenannte Watchpoints, die den App-Prozess anhalten, wenn Ihre App 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 über einen der beiden Zeiger auf diesen Speicherblock zugreifen.

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 Speicherblock zu, den das System dieser Variablen zuweist, nicht der Variablen selbst. Dies unterscheidet sich vom Hinzufügen einer Variablen zum Bereich „Watches“, mit dem Sie den Wert einer Variablen beobachten können, aber nicht den Anwendungsprozess anhalten können, wenn das System ihren Wert im Arbeitsspeicher liest oder ändert.

Hinweis:Wenn Ihr App-Prozess eine Funktion beendet und das System die lokalen Variablen aus dem Arbeitsspeicher deallociert, müssen Sie alle für diese Variablen erstellten Watchpoints neu zuweisen.

Damit Sie einen Watchpoint setzen können, müssen folgende Voraussetzungen erfüllt sein:

  • Ihr 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 auf 4 Byte für 32-Bit-Prozessoren oder 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 Variablendeklaration an, wie unten gezeigt:
    // For a 64-bit ARM processor
    int my_counter __attribute__((aligned(8)));
  • Du hast bereits drei oder weniger Wiedergabepunkte 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 Wiedergabepunkte.

Hinweis:Wenn Sie beim Debuggen Ihrer App mit 32-Bit-ARM-ABIs einen Watchpoint hinzufügen oder den Mauszeiger auf Variablen im Code bewegen, um ihre Werte zu prüfen, kann dies zu einem Absturz führen. Als Behelfslösung können Sie mit 64-Bit-ARM-, x86- oder x86_64-Binärdateien debuggen. Dieses Problem wird in einer zukünftigen Android Studio-Version behoben.

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

  1. Wenn Ihre App an einem Haltepunkt angehalten ist, rufen Sie in der LLDB-Sitzungsansicht den Bereich „Variablen“ auf.
  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 Watchpoints wird angezeigt (siehe Abbildung 9).

    Konfigurieren Sie den 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. Entfernen Sie das Häkchen bei dieser Option, wenn Sie dieses Verhalten nicht wünschen. 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 App den Watchpoint auslösen soll, wenn sie versucht, den Arbeitsspeicherblock zu lesen, den das System der Variablen zuweist, Lesen oder Schreiben. Wenn der Watchpoint bei einem Lese- oder Schreibvorgang ausgelöst werden soll, wählen Sie Beliebig aus.
  4. Klicken Sie auf Fertig.

Wenn Sie alle Ihre Haltepunkte aufrufen und die Einstellungen für Haltepunkte konfigurieren möchten, klicken Sie im Debugfenster auf Haltepunkte ansehen . Das Dialogfeld "Haltepunkte" wird angezeigt (siehe Abbildung 10).

Abbildung 10: Im Dialogfeld „Bruchstellen“ werden Ihre aktuellen Haltepunkte mit den zugehörigen Verhaltenseinstellungen aufgeführt.

Nachdem Sie den Watchpoint hinzugefügt haben, klicken Sie im Debugfenster auf Programm fortsetzen , um den App-Prozess fortzusetzen. Wenn Ihre App versucht, auf einen Speicherblock zuzugreifen, für den Sie einen Watchpoint festgelegt haben, wird der App-Prozess standardmäßig vom Android-System angehalten und neben der Codezeile, die Ihre App zuletzt ausgeführt hat, wird ein Watchpoint-Symbol  angezeigt (siehe Abbildung 11).

Abbildung 11. Android Studio zeigt die Codezeile an, die Ihre App ausführt, kurz bevor ein Watchpoint ausgelöst wird.

Anzeigeformat für Ressourcenwerte aufrufen und ändern

Im Debug-Modus können Sie Ressourcenwerte aufrufen und ein anderes Darstellungsformat für Variablen in Ihrem Java- oder Kotlin-Code auswählen. Wenn der Tab „Variablen“ angezeigt wird 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 Ansicht 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:Stringformat für die Anzeige.
    • Objekt:Die Definition des Objekts (eine Instanz einer Klasse) anzeigen.
    • Array:Die Daten werden in einem Arrayformat angezeigt.
    • Zeitstempel:Datum und Uhrzeit werden so angezeigt: TTJJJJ-MM-TT HH:MM:SS.
    • Auto:In Android Studio wird basierend auf dem Datentyp das beste Format ausgewählt.
    • Binär: Ein Binärwert wird mit Nullen und Einsen dargestellt.
    • MeasureSpec:Der Wert, der vom übergeordneten Element an das ausgewählte untergeordnete Element übergeben wird. Weitere Informationen finden Sie unter MeasureSpec.
    • Hex: Als Hexadezimalwert anzeigen.
    • Primär:Als numerischer Wert mit einem primitiven Datentyp anzeigen.
    • 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 Als aus.
  3. Wählen Sie Erstellen aus.
  4. Das Dialogfeld Java-Datentyp-Renderer wird angezeigt. Folgen Sie der Anleitung unter Java-Datentyp-Renderer.