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.
  • Haltepunkte in Ihrem Java-, Kotlin- und C/C++-Code festlegen
  • Variablen untersuchen und Ausdrücke zur Laufzeit auswerten

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

Debugging aktivieren

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

Aktivieren Sie das Debugging auf Ihrem Gerät.
Wenn Sie den Emulator verwenden, ist das Debugging standardmäßig aktiviert. Bei einem verbundenen Gerät müssen Sie jedoch das Debugging in den Entwickleroptionen des Geräts aktivieren.
Führen Sie eine debugfähige Build-Variante aus.

Verwenden Sie eine Build-Variante, die debuggable true (isDebuggable = true in Kotlin-Skripts) 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 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:

Groovy

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 App von einem Bibliotheksmodul abhängt, das Sie ebenfalls debuggen möchten, muss diese Bibliothek auch mit debuggable true verpackt werden, damit die zugehörigen Debugsymbole erhalten bleiben. Damit die debugfähigen Varianten Ihres App-Projekts die debugfähige Variante eines Bibliotheksmoduls erhalten, müssen Sie Nicht-Standardversionen Ihrer Bibliothek veröffentlichen.

Debugging 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ü für Zielgeräte
    Abbildung 1: Menü für Zielgeräte.

    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 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 dem Debugging zu beginnen. Wenn Sie dieselbe Instanz der App weiter ausführen möchten, klicken Sie auf Cancel Debug (Debuggen abbrechen) und hängen Sie den Debugger stattdessen an eine laufende App an. 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 C- und C++-Code zu Ihrem Projekt hinzufügen, führt Android Studio im Debug-Fenster auch den LLDB-Debugger aus, um Ihren nativen Code zu debuggen.

  4. Wenn das Debug-Fenster nicht geöffnet ist, wählen Sie View > Tool Windows > 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 Debugging 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 Choose Process (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 auswählen, um alle Prozesse zu sehen. Auf einem gerooteten Gerät werden alle Prozesse angezeigt, die auf dem Gerät ausgeführt werden. Auf einem Gerät ohne Root-Zugriff werden jedoch nur debugfähige Prozesse angezeigt.
    2. Im Menü Android-Debugger-Einstellungen verwenden aus können Sie eine vorhandene Konfiguration zum Ausführen/Debuggen auswählen. 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-/Debugkonfiguration haben, wählen Sie Neu erstellen aus. Durch diese Auswahl wird das Menü Debug-Typ aktiviert, in dem Sie einen anderen Debug-Typ auswählen können. Standardmäßig verwendet Android Studio den Debugging-Typ „Detect Automatically“ (Automatisch erkennen), um die beste Debugger-Option für Sie auszuwählen. Dabei wird berücksichtigt, ob Ihr Projekt Java- oder C/C++-Code enthält.
  3. Klicken Sie auf OK.

    Das Fenster „Debuggen“ wird angezeigt.

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

Das Debug-Fenster

Abbildung 2. Das Debugging-Fenster.

Das Debug-Fenster ist in folgende Bereiche unterteilt:

  1. Symbolleiste für Ausführung und Navigation (siehe Mit Haltepunkten arbeiten)
  2. Thread-Auswahl
  3. Bewertung und Eingabe von Watch-Ausdrücken Variablen untersuchen
  4. Stapelanzeige
  5. Bereich „Variablen“. Variablen untersuchen

Hinweis:Der Android Studio-Debugger und der Garbage Collector sind nur lose integriert. Die virtuelle Android-Maschine sorgt dafür, dass alle Objekte, die dem Debugger bekannt sind, erst nach dem Trennen der Verbindung durch den Debugger per 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 nach dem Trennen der Verbindung des Debuggers bereinigt, auch wenn der Thread beendet wurde.

Debuggertyp ändern

Da zum Debuggen von Java-/Kotlin-Code und C/C++-Code unterschiedliche Debugging-Tools erforderlich sind, können Sie im Android Studio-Debugger auswählen, welcher Debuggertyp verwendet werden soll. Standardmäßig entscheidet Android Studio anhand der Sprachen, die im Projekt erkannt werden, welcher Debugger verwendet wird. Dazu wird der Debuggertyp Automatisch erkennen verwendet.

Wenn Sie den Debugger in der Debug-Konfiguration manuell auswählen möchten, klicken Sie auf Run > Edit Configurations (Ausführen > Konfigurationen bearbeiten). Sie können den Debugger auch im Dialogfeld auswählen, das angezeigt wird, wenn Sie auf Run > Attach debugger to Android process (Ausführen > Debugger an Android-Prozess anhängen) klicken.

Die verfügbaren Debugging-Typen sind:

Automatisch erkennen
Wählen Sie diesen Debugging-Typ aus, wenn Android Studio automatisch die beste Option für den Code auswählen soll, den Sie debuggen. Wenn Sie beispielsweise C- oder C++-Code in Ihrem Projekt haben, verwendet Android Studio automatisch den Debugging-Typ „Dual“. Andernfalls verwendet Android Studio den Debugtyp „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-Only-Debugger ignoriert alle Haltepunkte oder Überwachungen, die Sie in Ihrem nativen Code festlegen.
Nur nativ (nur mit C/C++-Code verfügbar)
Wählen Sie diesen Debugging-Typ aus, wenn Sie nur LLDB zum Debuggen Ihres Codes verwenden möchten. Bei Verwendung dieses Debugging-Typs ist die Ansicht der Java-Debuggersitzung nicht verfügbar. Standardmäßig untersucht LLDB nur Ihren nativen Code und ignoriert Breakpoints in Ihrem Java-Code. Wenn Sie auch Ihren Java-Code debuggen möchten, wechseln Sie entweder zum Debugging-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.

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

    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 einen unknown key-Fehler aus. Wenn ptrace nicht aktiviert ist, wird ein anderer Wert als 0 ausgegeben.

Dual (Java + nativ) – nur mit C/C++-Code verfügbar
Wählen Sie diesen Debugging-Typ aus, wenn Sie zwischen dem Debugging von Java- und nativem Code wechseln möchten. Android Studio hängt sowohl den Java-Debugger als auch LLDB an den Prozess Ihrer App an, sodass Sie Breakpoints in Ihrem Java- und nativen Code untersuchen können, ohne Ihre App neu zu starten oder Ihre Debugkonfiguration zu ändern.

Abbildung 2 zeigt die beiden Tabs rechts neben dem Titel des Debugging-Fensters. Da die App sowohl Java- als auch C++-Code enthält, gibt es einen Tab zum Debuggen des nativen Codes und einen 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 Optimierungsflags verwenden, nimmt der Compiler Änderungen an Ihrem kompilierten Code vor, damit er effizienter ausgeführt wird. 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 Compiler-Optimierungen deaktivieren, wenn Sie Ihren nativen Code debuggen.

Systemprotokoll verwenden

Das Systemlog 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 Systemlog verwenden möchten, um Fehler in Ihrer App zu beheben, müssen Sie dafür sorgen, dass in Ihrem Code Lognachrichten geschrieben und der Stacktrace für Ausnahmen ausgegeben wird, während sich Ihre App in der Entwicklungsphase befindet.

Lognachrichten in Code schreiben

Verwenden Sie die Klasse Log, um Lognachrichten in Ihren Code zu schreiben. Mithilfe von Lognachrichten können Sie den Ausführungsablauf nachvollziehen, indem Sie die System-Debug-Ausgabe erfassen, während Sie mit Ihrer App interagieren. Lognachrichten 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 sehen Sie, wie Sie Logmeldungen hinzufügen können, um zu ermitteln, ob beim Starten Ihrer 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-Lognachrichten und Stacktrace-Ausgabeaufrufe aus Ihrem Code, wenn Sie Ihre App veröffentlichen. Setzen Sie dazu ein DEBUG-Flag und platzieren Sie Debug-Lognachrichten in bedingten Anweisungen.

Systemprotokoll ansehen

Sie können Debug- und andere Systemmeldungen im Logcat-Fenster ansehen und filtern, wie in Abbildung 4 dargestellt. Sie können beispielsweise Meldungen sehen, wenn die Garbage Collection erfolgt, oder Meldungen, die Sie Ihrer App 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 Breakpoints, die verschiedene Debugging-Aktionen auslösen. Es gibt verschiedene Arten von Haltepunkten:

Zeilenhaltepunkt
Der häufigste Typ ist ein Zeilenhaltepunkt, der die Ausführung Ihrer App an einer bestimmten Codezeile unterbricht. Während der Pause können Sie Variablen untersuchen, Ausdrücke auswerten und die Ausführung dann Zeile für Zeile fortsetzen, um die Ursachen von Laufzeitfehlern zu ermitteln.
Methodenhaltepunkt
Ein Methoden-Haltepunkt unterbricht die Ausführung Ihrer App, wenn sie eine bestimmte Methode aufruft oder verlässt. Während der Pause können Sie Variablen untersuchen, Ausdrücke auswerten und die Ausführung dann 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 aufgeführt. So können Sie leichter herausfinden, welche Änderungen die Neuzusammensetzung verursacht haben.
Feldhaltepunkt
Ein Feld-Haltepunkt unterbricht die Ausführung Ihrer App, wenn Daten aus einem bestimmten Feld gelesen oder in ein bestimmtes Feld geschrieben werden.
Ausnahme-Haltepunkt
Ein Ausnahme-Haltepunkt unterbricht die Ausführung Ihrer App, wenn eine Ausnahme ausgelöst wird.

Sie können bedingte Breakpoints festlegen, die die Ausführung nur unterbrechen, wenn bestimmte Bedingungen erfüllt sind. Sie können auch Logging-Breakpoints festlegen, die in Logcat schreiben, ohne die Ausführung zu unterbrechen. So können Sie vermeiden, dass Ihr Code mit Log-Anweisungen überladen wird.

So fügen Sie einen Zeilen-Haltepunkt hinzu:

  1. Suchen Sie die Codezeile, an der Sie die Ausführung pausieren möchten.
  2. Klicken Sie auf den linken Rand neben der entsprechenden Codezeile oder platzieren Sie den Cursor 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 Debug , 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 Ausführung Ihres Codes den Haltepunkt erreicht, wird die Ausführung Ihrer App in Android Studio angehalten.

So ermitteln Sie den Status der App:

  • 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 prüfen Sie, ob Variablen aktiviert ist.

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

  • Wenn Sie zur ersten Zeile in einem Methodenaufruf wechseln möchten, klicken Sie auf Step Into .

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

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

Wenn in Ihrem Projekt nativer Code verwendet wird, werden standardmäßig sowohl der Java-Debugger als auch LLDB als zwei separate Prozesse an Ihre App angehängt, wenn Sie den Debugtyp „Detect Automatically“ (Automatisch erkennen) verwenden. Sie können zwischen der Überprüfung von Java- und C/C++-Breakpoints wechseln, ohne die App neu zu starten oder Einstellungen zu ändern.

Hinweis:Damit Android Studio Breakpoints in Ihrem C- oder C++-Code erkennen kann, müssen Sie einen Debugging-Typ verwenden, der LLDB unterstützt, z. B. „Automatisch erkennen“, „Nativ“ oder „Dual“. Sie können den von Android Studio verwendeten Debugging-Typ ändern, indem Sie Ihre Debugging-Konfiguration bearbeiten. Weitere Informationen zu den verschiedenen Debugging-Typen finden Sie im Abschnitt zur Verwendung anderer Debugging-Typen.

Wenn Android Studio Ihre App auf dem Zielgerät bereitstellt, wird das Debug-Fenster mit einem Tab oder einer Ansicht für jede Debugging-Sitzung für jeden Debugger-Prozess geöffnet, wie in Abbildung 6 dargestellt.

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

    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 Fenster-Frames und zum Untersuchen von Variablen.

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

  2. Android Studio wechselt zum Tab <your-module>-java, wenn der Java-Debugger einen Haltepunkt in Ihrem Java- oder Kotlin-Code erreicht.
  3. Beim Debuggen 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 jedes Mal ausführen soll, wenn Sie mit dem Debuggen Ihrer App beginnen, entweder kurz vor oder kurz nach dem Anhängen des Debuggers an Ihren App-Prozess, können Sie diese Befehle Ihrer Debugkonfiguration hinzufügen.

Beim Debuggen von C/C++-Code können Sie auch spezielle Arten von Haltepunkten festlegen, sogenannte Überwachungspunkte, die den App-Prozess unterbrechen können, wenn Ihre App mit einem bestimmten Speicherblock interagiert. Weitere Informationen finden Sie 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 Debugging-Fenster auf Haltepunkte ansehen . Das Fenster „Breakpoints“ (Haltepunkte) wird angezeigt (siehe Abbildung 7).

Abbildung 7. Im Fenster „Breakpoints“ werden alle aktuellen Breakpoints aufgelistet. Außerdem sind Verhaltensweisen für jeden Breakpoint enthalten.

Im Fenster „Haltepunkte“ können Sie jeden Haltepunkt in der Liste im Bereich aktivieren oder deaktivieren. Wenn ein Haltepunkt deaktiviert ist, pausiert Android Studio Ihre App nicht, wenn sie diesen Haltepunkt erreicht.

Wählen Sie einen Haltepunkt aus der Liste aus, um seine Einstellungen zu konfigurieren. Sie können einen Haltepunkt so konfigurieren, dass er zuerst deaktiviert ist und das System ihn aktiviert, nachdem ein anderer Haltepunkt erreicht wurde. Sie können auch konfigurieren, ob ein Haltepunkt deaktiviert werden soll, nachdem er erreicht wurde. Wenn Sie einen Haltepunkt für eine beliebige Ausnahme festlegen möchten, wählen Sie in der Liste der Haltepunkte Exception Breakpoints aus.

Wenn Sie alle Haltepunkte vorübergehend deaktivieren möchten, klicken Sie im Debugging-Fenster auf Haltepunkte stummschalten . Klicken Sie noch einmal, um die Funktion wieder zu aktivieren.

Fehlerbehebung bei Fensterrahmen

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

Wählen Sie einen Thread über das Menü zur Threadauswahl aus und sehen Sie sich den zugehörigen Stackframe an. Klicken Sie auf die Elemente im Frame, um die Quelle im Editor zu öffnen. Sie können die Darstellung des Threads auch anpassen und den Stackframe exportieren, wie im Leitfaden zum Untersuchen von Frames beschrieben.

Variablen prüfen

Im Debugger-Fenster können Sie im Bereich „Variablen“ Variablen untersuchen, wenn das System Ihre App an einem Haltepunkt stoppt 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 auswerten, die im ausgewählten Frame verfügbar sind.

So fügen Sie dem Objektbaum einen Ausdruck hinzu (während die Anwendung debuggt wird):

Abbildung 8. Der Objektbaum und das Eingabefeld für Ausdrücke im Debugging-Fenster.
  1. Geben Sie den Ausdruck ein, der beobachtet oder angezeigt werden soll.
  2. Klicken Sie auf Zu Überwachungen hinzufügen oder drücken Sie die Eingabetaste, um den Ausdruck einmal auszuwerten.

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

Überwachte Ausdrücke werden aktualisiert, wenn Haltepunkte erreicht werden oder Sie den Code schrittweise durchlaufen.

Ausgewertete Ausdrücke werden oben im Objektbaum angezeigt, bis Sie manuell einen anderen Ausdruck 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 Beobachtung entfernen.

Hinweise hinzufügen

Beim Debuggen von C/C++-Code können Sie spezielle Arten von Haltepunkten festlegen, sogenannte Beobachtungspunkte, mit denen der App-Prozess angehalten werden kann, wenn Ihre App mit einem bestimmten Speicherblock interagiert. Wenn Sie beispielsweise zwei Zeiger auf einen Speicherblock festlegen und ihm einen Haltepunkt zuweisen, wird der Haltepunkt ausgelöst, wenn Sie mit einem der beiden Zeiger auf diesen Speicherblock zugreifen.

In Android Studio können Sie während der Laufzeit einen Beobachtungspunkt erstellen, indem Sie eine bestimmte Variable auswählen. LLDB weist den Beobachtungspunkt jedoch nur dem Speicherblock zu, den das System dieser Variablen zuweist, nicht der Variablen selbst. Das ist etwas anderes, als eine Variable dem Bereich „Watches“ hinzuzufügen. Dadurch können Sie zwar den Wert einer Variablen beobachten, aber den App-Prozess nicht anhalten, wenn das System den Wert im Arbeitsspeicher liest oder ändert.

Hinweis:Wenn der App-Prozess eine Funktion beendet und das System die lokalen Variablen aus dem Speicher freigibt, müssen Sie alle für diese Variablen erstellten Haltepunkte neu zuweisen.

Damit Sie einen Haltepunkt für Variablen festlegen können, müssen die folgenden Voraussetzungen erfüllt sein:

  • Auf Ihrem physischen Zielgerät oder Emulator wird eine x86- oder x86_64-CPU verwendet. Wenn auf Ihrem Gerät eine ARM-CPU verwendet wird, müssen Sie die Grenze der Adresse Ihrer Variablen im Arbeitsspeicher entweder an 4 Bytes (für 32-Bit-Prozessoren) oder an 8 Bytes (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)));
  • Sie haben bereits drei oder weniger Beobachtungspunkte 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 Ihre App mit 32-Bit-ARM-ABIs debuggen, kann es zu einem Absturz kommen, wenn Sie einen Haltepunkt hinzufügen oder den Mauszeiger auf Variablen im Code bewegen, um ihre Werte zu untersuchen. Als Behelfslösung können Sie 64-Bit-ARM-, x86- oder x86_64-Binärdateien zum Debuggen verwenden. Dieses Problem wird in einer zukünftigen Android Studio-Version behoben.

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

  1. Während Ihre App an einem Haltepunkt angehalten wird, rufen Sie in der LLDB-Sitzungsansicht den Bereich „Variablen“ auf.
  2. Klicken Sie mit der rechten Maustaste auf eine Variable, die den Speicherblock belegt, den Sie beobachten möchten, und wählen Sie Add Watchpoint (Beobachtungspunkt hinzufügen) aus.

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

    Konfigurieren Sie den Watchpoint mit den folgenden Optionen:

    • Aktiviert:Deaktivieren Sie diese Option, wenn Android Studio den Haltepunkt ignorieren soll, bis Sie die Einstellung ändern. Android Studio speichert den Watchpoint, damit Sie später darauf zugreifen können.
    • Anhalten:Standardmäßig hält das Android-System den Prozess Ihrer App an, wenn es auf einen Speicherblock zugreift, den Sie einem Watchpoint zuweisen. Wenn Sie dieses Verhalten nicht wünschen, deaktivieren Sie die Option. Dadurch werden zusätzliche Optionen angezeigt, mit denen Sie das Verhalten anpassen können, wenn das System mit Ihrem Watchpoint interagiert: Log message to console (Meldung in der Konsole protokollieren) und Remove when hit (Entfernen, wenn erreicht).
    • Zugriffstyp:Wählen Sie aus, ob Ihr Watchpoint ausgelöst werden soll, wenn Ihre App versucht, Read (Lesen) oder Write (Schreiben) für den Speicherblock auszuführen, den das System der Variablen zuweist. 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 Debug-Fenster auf Haltepunkte ansehen . Das Dialogfeld „Breakpoints“ (Haltepunkte) wird angezeigt (siehe Abbildung 10).

Abbildung 10: Im Dialogfeld „Breakpoints“ werden Ihre aktuellen Watchpoints aufgeführt. Außerdem sind dort Verhaltensweisen für die einzelnen Watchpoints festgelegt.

Klicken Sie nach dem Hinzufügen des Watchpoints im Debug-Fenster auf Programm fortsetzen , um den App-Prozess fortzusetzen. Wenn Ihre App standardmäßig versucht, auf einen Speicherblock zuzugreifen, für den Sie einen Haltepunkt festgelegt haben, wird der App-Prozess vom Android-System angehalten und neben der zuletzt ausgeführten Codezeile Ihrer App wird ein Haltepunktsymbol  angezeigt (siehe Abbildung 11).

Abbildung 11. Android Studio gibt die Codezeile an, die Ihre App kurz vor dem Auslösen eines Beobachtungspunkts 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. Gehen Sie so vor, wenn der Tab „Variablen“ angezeigt und ein Frame ausgewählt ist:

  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 sehen Sie eine oder mehrere der folgenden Optionen:

    • Klasse:Zeigt die Klassendefinition an.
    • toString:Format des Anzeigestrings.
    • Objekt:Zeigt die Definition des Objekts (einer Instanz einer Klasse) an.
    • Array:Anzeige im Arrayformat.
    • Zeitstempel: Datum und Uhrzeit werden im Format „JJJJ-MM-TT HH:MM:SS“ angezeigt.
    • Auto:Android Studio wählt das beste Format basierend auf dem Datentyp aus.
    • Binär:Binärwerte werden mit Nullen und Einsen dargestellt.
    • MeasureSpec:Der Wert, der vom übergeordneten an das ausgewählte untergeordnete Element übergeben wird. Weitere Informationen finden Sie unter MeasureSpec.
    • Hex:Als Hexadezimalwert anzeigen.
    • Primitive:Als numerischer Wert mit einem primitiven Datentyp anzeigen.
    • Ganzzahl:Als numerischer Wert des Typs Integer anzeigen.

So erstellen Sie ein benutzerdefiniertes Format:

  1. Klicken Sie mit der rechten Maustaste auf den Ressourcenwert.
  2. Wählen Sie Anzeigen als aus.
  3. Wählen Sie Erstellen aus.
  4. Das Dialogfeld Java Data Type Renderers wird angezeigt. Folgen Sie der Anleitung unter Java-Datentyp-Renderer.