Debugowanie aplikacji

Android Studio udostępnia debuger, który umożliwia m.in. te czynności:

  • Wybierz urządzenie, na którym chcesz debugować aplikację.
  • Ustawiaj punkty przerwania w kodzie Java, Kotlin i C/C++.
  • Sprawdzaj zmienne i obliczaj wyrażenia w czasie działania.

Ta strona zawiera instrukcje dotyczące podstawowych operacji debugera. Więcej informacji znajdziesz w dokumentacji debugowania w IntelliJ IDEA.

Włączanie debugowania

Zanim zaczniesz debugować, wykonaj te czynności:

Włącz debugowanie na urządzeniu.
Jeśli używasz emulatora, debugowanie jest domyślnie włączone. W przypadku połączonego urządzenia musisz jednak włączyć debugowanie w opcjach programisty.
Uruchom wersję kompilacji z możliwością debugowania.

Użyj wariantu kompilacji, który zawiera debuggable true (isDebuggable = true w skryptach Kotlin) w konfiguracji kompilacji.

Zwykle możesz wybrać domyślny wariant „debug”, który jest uwzględniony w każdym projekcie Android Studio, nawet jeśli nie jest widoczny w pliku build.gradle. Jeśli jednak zdefiniujesz nowe typy kompilacji, które powinny być debugowane, musisz dodać do nich ten kod: debuggable true

Groovy

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

Kotlin

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

Ta właściwość dotyczy też modułów z kodem C/C++.

Uwaga: właściwość jniDebuggable nie jest już używana.

Jeśli aplikacja jest zależna od modułu biblioteki, który też chcesz debugować, ta biblioteka musi być również spakowana za pomocą debuggable true, aby zachować symbole debugowania. Aby mieć pewność, że wersje aplikacji z możliwością debugowania otrzymają wersję modułu biblioteki z możliwością debugowania, opublikuj wersje biblioteki inne niż domyślne.

Rozpocznij debugowanie

Sesję debugowania możesz rozpocząć w ten sposób:

  1. Ustaw punkty przerwania w kodzie aplikacji.
  2. Na pasku narzędzi wybierz urządzenie, na którym chcesz debugować aplikację, z menu urządzenia docelowego.
    Menu urządzenia docelowego.
    Rysunek 1. Menu urządzenia docelowego.

    Jeśli nie masz skonfigurowanych żadnych urządzeń, musisz podłączyć urządzenie przez USB, podłączyć urządzenie przez Wi-Fi lub utworzyć AVD, aby używać emulatora Androida.

  3. Na pasku narzędzi kliknij Debuguj .

    Jeśli aplikacja jest już uruchomiona na urządzeniu, pojawi się okno z pytaniem, czy chcesz przełączyć się z trybu Uruchom na tryb Debuguj. Aby rozpocząć debugowanie, musisz ponownie uruchomić urządzenie. Aby pozostawić uruchomioną tę samą instancję aplikacji, kliknij Anuluj debugowanie i zamiast tego dołącz debuger do uruchomionej aplikacji. W przeciwnym razie Android Studio utworzy plik APK, podpisze go kluczem debugowania, zainstaluje na wybranym urządzeniu i uruchomi.

    Jeśli dodasz do projektu kod w językach C i C++, Android Studio uruchomi też w oknie Debugowanie debugger LLDB, aby debugować kod natywny.

  4. Jeśli okno Debugowanie nie jest otwarte, wybierz Widok > Okna narzędzi > Debugowanie lub kliknij Debugowanie na pasku okna narzędzi.

Dołączanie debugera do działającej aplikacji

Jeśli aplikacja jest już uruchomiona na urządzeniu, możesz rozpocząć debugowanie bez ponownego uruchamiania aplikacji w ten sposób:

  1. Kliknij Dołączanie debugera do procesu Androida .
  2. W oknie Wybierz proces wybierz proces, do którego chcesz dołączyć debuger.
    1. Jeśli używasz emulatora lub urządzenia z dostępem do roota, możesz zaznaczyć opcję Pokaż wszystkie procesy, aby wyświetlić wszystkie procesy. Na urządzeniu z dostępem do roota wyświetli wszystkie procesy działające na urządzeniu. Na urządzeniu bez roota będą jednak wyświetlane tylko procesy, które można debugować.
    2. W menu Use Android Debugger Settings from (Użyj ustawień debugera Androida z) możesz wybrać istniejącą konfigurację uruchamiania/debugowania. W przypadku kodu w językach C i C++ umożliwia to ponowne użycie poleceń uruchamiania LLDB, poleceń LLDB po dołączeniu i katalogów symboli w istniejącej konfiguracji.
    3. Jeśli nie masz istniejącej konfiguracji uruchamiania/debugowania, kliknij Utwórz nową. Po wybraniu tej opcji pojawi się menu Typ debugowania, w którym możesz wybrać inny typ debugowania. Domyślnie Android Studio używa typu debugowania Wykryj automatycznie, aby wybrać najlepszą opcję debugera na podstawie tego, czy projekt zawiera kod w Javie czy w C/C++.
  3. Kliknij OK.

    Pojawi się okno Debugowanie.

Na karcie Procesy w Eksploratorze urządzeń (Widok > Okna narzędzi > Eksplorator urządzeń) znajduje się też lista procesów, które można debugować. Możesz wybrać proces i wykonać operację zakończenia , wymuszonego zatrzymania lub dołączenia debugera do danego procesu .

Okno debugowania

Rysunek 2. Okno Debug.

Okno debugowania jest podzielone na

  1. Pasek narzędzi wykonywania i nawigacji. Zobacz Praca z punktami przerwania
  2. Selektor wątków
  3. Ocena i wpisywanie wyrażeń do obserwowania. Zobacz Sprawdzanie zmiennych.
  4. Wyświetlanie stosu
  5. Panel Zmienne. Zobacz Sprawdzanie zmiennych.

Uwaga: debugger Android Studio i mechanizm odśmiecania są luźno zintegrowane. Wirtualna maszyna Androida gwarantuje, że żaden obiekt, o którym wie debuger, nie zostanie usunięty z pamięci do czasu odłączenia debugera. Może to spowodować gromadzenie się obiektów podczas połączenia z debugerem. Jeśli na przykład debuger wykryje działający wątek, powiązany z nim obiekt Thread nie zostanie usunięty z pamięci do czasu odłączenia debugera, nawet jeśli wątek został zakończony.

Zmiana typu debugera

Do debugowania kodu w Javie/Kotlinie i kodu w C/C++ wymagane są różne narzędzia do debugowania, dlatego debugger Androida Studio umożliwia wybór typu debuggera. Domyślnie Android Studio decyduje, którego debugera użyć, na podstawie języków wykrytych w projekcie. W tym celu korzysta z typu debugera Wykrywaj automatycznie.

Aby ręcznie wybrać debuger w konfiguracji debugowania, kliknij Uruchom > Edytuj konfiguracje. Możesz też wybrać debuger w oknie dialogowym, które pojawi się po kliknięciu Uruchom > Dołącz debuger do procesu Androida.

Dostępne typy debugowania:

Wykrywaj automatycznie
Wybierz ten typ debugowania, jeśli chcesz, aby Android Studio automatycznie wybierało najlepszą opcję dla debugowanego kodu. Jeśli na przykład w projekcie masz kod w języku C lub C++, Android Studio automatycznie użyje typu debugowania podwójnego. W przeciwnym razie Android Studio używa typu debugowania Java-Only.
Tylko Java
Wybierz ten typ debugowania, jeśli chcesz debugować tylko kod napisany w języku Java lub Kotlin. Debuger Java-Only ignoruje wszystkie punkty przerwania i obserwacje ustawione w kodzie natywnym.
Tylko natywne (dostępne tylko w przypadku kodu C/C++)
Wybierz ten typ debugowania, jeśli do debugowania kodu chcesz używać tylko LLDB. W przypadku tego typu debugowania widok sesji debugera Java jest niedostępny. Domyślnie LLDB sprawdza tylko kod natywny i ignoruje punkty przerwania w kodzie Java. Jeśli chcesz też debugować kod Java, przełącz się na typ debugowania Wykryj automatycznie lub Podwójne debugowanie.

Debugowanie natywne działa tylko na urządzeniach spełniających te wymagania:

  • Urządzenie obsługuje run-as.

    Aby sprawdzić, czy urządzenie obsługuje run-as, uruchom to polecenie w powłoce ADB połączonej z urządzeniem:

    run-as your-package-name pwd
    

    Zastąp your-package-name nazwą pakietu aplikacji. Jeśli urządzenie obsługuje run-as, polecenie powinno zostać zwrócone bez błędów.

  • Na urządzeniu jest włączona funkcja ptrace.

    Aby sprawdzić, czy funkcja ptrace jest włączona, uruchom to polecenie w powłoce ADB połączonej z urządzeniem:

    sysctl kernel.yama.ptrace_scope
    

    Jeśli opcja ptrace jest włączona, polecenie wydrukuje wartość 0 lub błąd unknown key. Jeśli ptrace nie jest włączona, zostanie wydrukowana wartość inna niż 0.

Podwójny (Java + kod natywny) – dostępny tylko w przypadku kodu C/C++
Wybierz ten typ debugowania, jeśli chcesz przełączać się między debugowaniem kodu Java i kodu natywnego. Android Studio dołącza do procesu aplikacji zarówno debuger Java, jak i LLDB, dzięki czemu możesz sprawdzać punkty przerwania w kodzie Java i natywnym bez ponownego uruchamiania aplikacji ani zmiany konfiguracji debugowania.

Na ilustracji 2 zwróć uwagę na 2 karty po prawej stronie tytułu okna Debugowanie. Aplikacja zawiera kod w językach Java i C++, więc jedna karta służy do debugowania kodu natywnego, a druga – kodu Java, co wskazuje sufiks -java.

Rysunek 3. karta do debugowania kodu natywnego i karta do debugowania kodu Java.

Uwaga: podczas debugowania kodu natywnego zoptymalizowanego przez kompilator możesz zobaczyć to ostrzeżenie:
This function was compiled with optimizations enabled. Some debugger features may not be available. Gdy używasz flag optymalizacji, kompilator wprowadza zmiany w skompilowanym kodzie, aby zwiększyć jego wydajność. Może to spowodować, że debuger będzie zgłaszać nieoczekiwane lub nieprawidłowe informacje, ponieważ trudno mu będzie mapować zoptymalizowany skompilowany kod z powrotem na oryginalny kod źródłowy. Z tego powodu podczas debugowania kodu natywnego należy wyłączyć optymalizacje kompilatora.

Korzystanie z dziennika systemowego

Dziennik systemowy wyświetla komunikaty systemowe podczas debugowania aplikacji. Komunikaty te zawierają informacje z aplikacji działających na urządzeniu. Jeśli chcesz używać dziennika systemowego do debugowania aplikacji, upewnij się, że Twój kod zapisuje komunikaty dziennika i wyświetla ślad stosu w przypadku wyjątków, gdy aplikacja jest w fazie rozwoju.

Pisanie wiadomości dziennika w kodzie

Aby pisać wiadomości dziennika w kodzie, użyj klasy Log. Komunikaty logu pomagają zrozumieć przebieg wykonywania, ponieważ zbierają dane wyjściowe debugowania systemu podczas interakcji z aplikacją. Komunikaty logu mogą też informować o tym, która część aplikacji nie działa prawidłowo. Więcej informacji o logowaniu znajdziesz w artykule Pisanie i wyświetlanie logów za pomocą Logcata.

Poniższy przykład pokazuje, jak dodać komunikaty dziennika, aby sprawdzić, czy informacje o poprzednim stanie są dostępne po rozpoczęciu aktywności:

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 */
        }
        ...
    }
}

Podczas programowania kod może też przechwytywać wyjątki i zapisywać zrzut stosu w dzienniku systemowym:

Kotlin

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

Java

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

Uwaga: gdy aplikacja będzie gotowa do opublikowania, usuń z kodu komunikaty dziennika debugowania i wywołania drukowania zrzutu stosu. Aby to zrobić, ustaw flagę DEBUG i umieść komunikaty dziennika debugowania w instrukcjach warunkowych.

Wyświetlanie dziennika systemowego

W oknie Logcat możesz wyświetlać i filtrować komunikaty debugowania oraz inne komunikaty systemowe, jak pokazano na rysunku 4. Możesz na przykład wyświetlać komunikaty, które pojawiają się podczas odśmiecania pamięci, lub komunikaty dodane do aplikacji za pomocą klasy Log.

Aby użyć Logcat, rozpocznij debugowanie i wybierz kartę Logcat.

Rysunek 4. Okno Logcat z ustawieniami filtra.

Opis Logcat i jego opcji filtrowania znajdziesz w artykule Zapisywanie i wyświetlanie logów za pomocą Logcat.

Praca z punktami przerwania

Android Studio obsługuje punkty przerwania, które wywołują różne działania debugowania. Istnieje kilka typów punktów przerwania:

Punkt przerwania wiersza
Najpopularniejszym typem jest punkt przerwania wiersza, który wstrzymuje wykonywanie aplikacji w określonym wierszu kodu. Podczas wstrzymania możesz sprawdzić zmienne, ocenić wyrażenia, a następnie kontynuować wykonywanie wiersz po wierszu, aby określić przyczyny błędów czasu działania.
Punkt przerwania metody
Punkt przerwania metody wstrzymuje wykonywanie aplikacji, gdy wchodzi ona do określonej metody lub z niej wychodzi. Podczas wstrzymania możesz sprawdzić zmienne, ocenić wyrażenia, a następnie kontynuować wykonywanie wiersz po wierszu, aby określić przyczyny błędów czasu działania. Gdy ustawisz punkt przerwania w funkcji kompozycyjnej, debuger wyświetli listę parametrów funkcji kompozycyjnej i ich stan, aby pomóc Ci określić, które zmiany mogły spowodować ponowne komponowanie.
Punkt przerwania pola
Punkt przerwania w polu wstrzymuje wykonywanie aplikacji, gdy odczytuje ona dane z określonego pola lub zapisuje w nim dane.
Punkt przerwania wyjątku
Punkt przerwania wyjątku wstrzymuje wykonywanie aplikacji, gdy zostanie zgłoszony wyjątek.

Możesz ustawić warunkowe punkty przerwania, które wstrzymują wykonywanie tylko wtedy, gdy zostaną spełnione określone warunki. Możesz też ustawić punkty przerwania rejestrowania, które zapisują dane w Logcat bez wstrzymywania wykonywania. Pozwala to uniknąć zaśmiecania kodu instrukcjami logowania.

Aby dodać punkt przerwania w wierszu, wykonaj te czynności:

  1. Znajdź wiersz kodu, w którym chcesz wstrzymać wykonanie.
  2. Kliknij lewy margines wzdłuż tego wiersza kodu lub umieść kursor w tym wierszu i naciśnij Control+F8 (w systemie macOS Command+F8).
  3. Jeśli aplikacja jest już uruchomiona, kliknij Dołącz debuger do procesu Androida . Aby rozpocząć debugowanie, kliknij Debuguj .

Po ustawieniu punktu przerwania obok wiersza pojawi się czerwona kropka, jak pokazano na rysunku 5.

Rysunek 5. Gdy ustawisz punkt przerwania, obok wiersza pojawi się czerwona kropka.

Gdy wykonanie kodu osiągnie punkt przerwania, Android Studio wstrzyma działanie aplikacji.

Aby określić stan aplikacji, użyj narzędzi na karcie Debuger:

  • Aby sprawdzić drzewo obiektów zmiennej, rozwiń je w widoku Zmienne. Jeśli widok Zmienne nie jest widoczny, kliknij Ustawienia układu i upewnij się, że zaznaczona jest opcja Zmienne.

  • Aby przejść do następnego wiersza kodu bez wpisywania metody, kliknij Krok dalej .

  • Aby przejść do pierwszego wiersza w wywołaniu metody, kliknij Krok do wnętrza .

  • Aby przejść do następnego wiersza poza bieżącą metodą, kliknij Krok wyjścia .

  • Aby kontynuować normalne działanie aplikacji, kliknij Wznów program .

Jeśli projekt korzysta z kodu natywnego, domyślnie typ debugowania Wykryj automatycznie dołącza do aplikacji zarówno debuger Javy, jak i LLDB jako 2 osobne procesy. Możesz przełączać się między sprawdzaniem punktów przerwania w kodzie Java i C/C++ bez ponownego uruchamiania aplikacji ani zmiany ustawień.

Uwaga: aby Android Studio wykrywał punkty przerwania w kodzie C lub C++, musisz użyć typu debugowania, który obsługuje LLDB, np. Wykryj automatycznie, Natywny lub Podwójny. Typ debugowania używany przez Android Studio możesz zmienić, edytując konfigurację debugowania. Aby dowiedzieć się więcej o różnych typach debugowania, przeczytaj sekcję dotyczącą korzystania z innych typów debugowania.

Gdy Android Studio wdraża aplikację na urządzeniu docelowym, otwiera się okno Debugowanie z kartą lub widokiem sesji debugowania dla każdego procesu debugera, jak pokazano na rysunku 6.

Rysunek 6. Debugowanie kodu natywnego za pomocą LLDB.
  1. Gdy debuger LLDB napotka punkt przerwania w kodzie C/C++, Android Studio przełączy się na kartę <your-module>. Panele Ramki, Zmienne i Obserwowane są również dostępne i działają dokładnie tak samo, jak w przypadku debugowania kodu w Javie.

    Chociaż w widoku sesji LLDB nie jest dostępny panel Wątki, możesz uzyskać dostęp do procesów aplikacji, korzystając z listy w panelu Ramki. Więcej informacji o tych panelach znajdziesz w sekcjach dotyczących debugowania ramek okiensprawdzania zmiennych.

    Uwaga: podczas sprawdzania punktu przerwania w kodzie natywnym system Android wstrzymuje maszynę wirtualną, która uruchamia kod bajtowy Javy aplikacji. Oznacza to, że podczas sprawdzania punktu przerwania w kodzie natywnym nie możesz wchodzić w interakcje z debugerem Java ani pobierać żadnych informacji o stanie z sesji debugera Java.

  2. Gdy debuger Java napotka punkt przerwania w kodzie Java lub Kotlin, Android Studio przełączy się na kartę <your-module>-java.
  3. Podczas debugowania za pomocą LLDB możesz użyć terminala LLDB w widoku sesji LLDB, aby przekazywać opcje wiersza poleceń do LLDB. Jeśli masz określone polecenia, które chcesz, aby LLDB wykonywał za każdym razem, gdy rozpoczynasz debugowanie aplikacji, tuż przed lub tuż po tym, jak debugger dołączy do procesu aplikacji, możesz dodać te polecenia do konfiguracji debugowania.

Podczas debugowania kodu C/C++ możesz też ustawić specjalne typy punktów przerwania, zwane punktami obserwacji, które mogą wstrzymać proces aplikacji, gdy aplikacja wchodzi w interakcję z określonym blokiem pamięci. Więcej informacji znajdziesz w sekcji dotyczącej dodawania punktów obserwacji.

Wyświetlanie i konfigurowanie punktów przerwania

Aby wyświetlić wszystkie punkty przerwania i skonfigurować ich ustawienia, w oknie Debugowanie kliknij Wyświetl punkty przerwania . Pojawi się okno Punktów przerwania, jak pokazano na rysunku 7.

Rysunek 7. W oknie Punktów przerwania wyświetlana jest lista wszystkich bieżących punktów przerwania wraz z ustawieniami dotyczącymi ich działania.

W oknie Punkty przerwania możesz włączyć lub wyłączyć każdy punkt przerwania z listy w panelu. Jeśli punkt przerwania jest wyłączony, Android Studio nie wstrzymuje działania aplikacji po osiągnięciu tego punktu.

Wybierz punkt przerwania z listy, aby skonfigurować jego ustawienia. Możesz skonfigurować punkt przerwania tak, aby był początkowo wyłączony, a system włączał go po osiągnięciu innego punktu przerwania. Możesz też skonfigurować, czy punkt przerwania ma być wyłączany po jego osiągnięciu. Aby ustawić punkt przerwania dla dowolnego wyjątku, na liście punktów przerwania wybierz Exception Breakpoints (Punkty przerwania wyjątku).

Aby tymczasowo wyłączyć wszystkie punkty przerwania, w oknie Debugowanie kliknij Wycisz punkty przerwania . Kliknij ponownie, aby ponownie włączyć.

Ramki okna debugowania

W oknie Debuger w panelu Ramki możesz sprawdzić ramkę stosu, która spowodowała osiągnięcie bieżącego punktu przerwania. Umożliwia to poruszanie się po ramce stosu i jej analizowanie, a także sprawdzanie listy wątków w aplikacji na Androida.

Aby wybrać wątek, użyj menu selektora wątków i wyświetl jego ramkę stosu. Kliknij elementy w ramce, aby otworzyć źródło w edytorze. Możesz też dostosować prezentację wątku i wyeksportować ramkę stosu zgodnie z opisem w  przewodniku Sprawdzanie ramek.

Sprawdzanie zmiennych

W oknie debugera panel Zmienne umożliwia sprawdzanie zmiennych, gdy system zatrzyma aplikację w punkcie przerwania i wybierzesz ramkę w panelu Ramki. Panel Zmienne umożliwia też ocenę wyrażeń ad hoc za pomocą metod statycznych lub zmiennych dostępnych w wybranej ramce.

Aby dodać wyrażenie do drzewa obiektów (podczas debugowania aplikacji):

Rysunek 8. Drzewo obiektów i pole wpisywania wyrażeń w oknie Debugowanie.
  1. Wpisz wyrażenie, które chcesz obserwować lub wyświetlać.
  2. Kliknij Dodaj do obserwatorów lub naciśnij Enter, aby jednorazowo obliczyć wartość wyrażenia.

Jeśli w drzewie obiektów znajduje się wyrażenie, które chcesz obserwować, możesz przeciągnąć je na górę drzewa, aby dodać je jako obserwowane wyrażenie.

Obserwowane wyrażenia będą się aktualizować po osiągnięciu punktów przerwania lub przejściu przez kod.

Obliczone wyrażenia będą wyświetlane u góry drzewa obiektów, dopóki nie obliczysz ręcznie innego wyrażenia lub nie przejdziesz do następnego kroku w kodzie.

Aby usunąć obserwowany wyrażenie z drzewa obiektów, kliknij je prawym przyciskiem myszy, a następnie kliknij Usuń obserwowanie.

Dodawanie punktów kontrolnych

Podczas debugowania kodu C/C++ możesz ustawić specjalne typy punktów przerwania, zwane punktami obserwacji, które mogą wstrzymać proces aplikacji, gdy aplikacja wchodzi w interakcję z określonym blokiem pamięci. Jeśli na przykład ustawisz 2 wskaźniki na blok pamięci i przypiszesz do niego punkt obserwacji, użycie dowolnego wskaźnika do uzyskania dostępu do tego bloku pamięci spowoduje wywołanie punktu obserwacji.

W Android Studio możesz utworzyć punkt obserwacji w czasie działania programu, wybierając konkretną zmienną, ale LLDB przypisuje punkt obserwacji tylko do bloku pamięci, który system przydziela do tej zmiennej, a nie do samej zmiennej. Różni się to od dodania zmiennej do panelu Obserwowane, co umożliwia obserwowanie wartości zmiennej, ale nie pozwala zawiesić procesu aplikacji, gdy system odczytuje lub zmienia jej wartość w pamięci.

Uwaga: gdy proces aplikacji opuści funkcję, a system zwolni z pamięci jej zmienne lokalne, musisz ponownie przypisać punkty obserwacji utworzone dla tych zmiennych.

Aby ustawić punkt obserwacji, musisz spełniać te wymagania:

  • Docelowe urządzenie fizyczne lub emulator korzysta z procesora x86 lub x86_64. Jeśli urządzenie korzysta z procesora ARM, musisz wyrównać granicę adresu zmiennej w pamięci do 4 bajtów w przypadku procesorów 32-bitowych lub 8 bajtów w przypadku procesorów 64-bitowych. Aby wyrównać zmienną w kodzie natywnym, w deklaracji zmiennej podaj __attribute__((aligned(num_bytes))), jak pokazano poniżej:
    // For a 64-bit ARM processor
    int my_counter __attribute__((aligned(8)));
  • Masz już przypisane maksymalnie 3 punkty obserwacyjne. Android Studio obsługuje tylko maksymalnie 4 punkty obserwacji na urządzeniach docelowych x86 lub x86_64. Inne urządzenia mogą obsługiwać mniejszą liczbę punktów obserwacji.

Uwaga: podczas debugowania aplikacji z 32-bitowymi interfejsami ABI ARM dodanie punktu obserwacji lub najechanie kursorem na zmienne w kodzie w celu sprawdzenia ich wartości może spowodować awarię. Aby obejść ten problem, debuguj za pomocą plików binarnych 64-bitowych ARM, x86 lub x86_64. Ten problem zostanie rozwiązany w przyszłej wersji Androida Studio.

Jeśli spełniasz wymagania, możesz dodać punkt obserwacyjny w ten sposób:

  1. Gdy aplikacja jest zawieszona w punkcie przerwania, przejdź do okienka Variables (Zmienne) w widoku sesji LLDB.
  2. Kliknij prawym przyciskiem myszy zmienną, która zajmuje blok pamięci, który chcesz śledzić, i wybierz Add Watchpoint (Dodaj punkt obserwacji).

    Rysunek 9. Dodaj punkt obserwacji do zmiennej w pamięci.
  3. Pojawi się okno konfiguracji punktu obserwacji, jak pokazano na rysunku 9.

    Skonfiguruj punkt obserwacji, korzystając z tych opcji:

    • Włączone: odznacz tę opcję, jeśli chcesz, aby Android Studio ignorowało punkt obserwacji do czasu zmiany tego ustawienia. Android Studio zapisuje punkt obserwacji, aby można było z niego później korzystać.
    • Zawieszenie: domyślnie system Android zawiesza proces aplikacji, gdy uzyskuje ona dostęp do bloku pamięci przypisanego do punktu obserwacji. Odznacz tę opcję, jeśli nie chcesz, aby tak się działo. Spowoduje to wyświetlenie dodatkowych opcji, których możesz użyć, aby dostosować działanie systemu, gdy napotka on punkt kontrolny: Zapisz wiadomość w konsoliUsuń po napotkaniu.
    • Typ dostępu: wybierz, czy punkt przerwania ma być wywoływany, gdy aplikacja próbuje odczytać lub zapisać blok pamięci przydzielony przez system do zmiennej. Aby punkt śledzenia został wywołany podczas odczytu lub zapisu, wybierz Dowolny.
  4. Kliknij Gotowe.

Aby wyświetlić wszystkie punkty obserwacji i skonfigurować ich ustawienia, w oknie Debugowanie kliknij Wyświetl punkty przerwania. Wyświetli się okno dialogowe Breakpoints (Punkty przerwania), jak pokazano na rysunku 10.

Rysunek 10. W oknie dialogowym Punkty przerwania wyświetlana jest lista bieżących punktów obserwacji oraz ustawienia dotyczące ich działania.

Po dodaniu punktu obserwacji kliknij Wznów program w oknie Debugowanie, aby wznowić proces aplikacji. Domyślnie, jeśli aplikacja spróbuje uzyskać dostęp do bloku pamięci, w którym ustawiono punkt obserwacji, system Android wstrzyma proces aplikacji, a obok ostatniej wykonanej przez nią linii kodu pojawi się ikona punktu obserwacji , jak pokazano na rysunku 11.

Rysunek 11. Android Studio wskazuje wiersz kodu, który aplikacja wykonuje tuż przed wywołaniem punktu obserwacji.

Wyświetlanie i zmienianie formatu wyświetlania wartości zasobów

W trybie debugowania możesz wyświetlać wartości zasobów i wybierać inny format wyświetlania zmiennych w kodzie Java lub Kotlin. Na karcie Zmienne, po wybraniu ramki:

  1. Na liście zmiennych kliknij prawym przyciskiem myszy dowolne miejsce w wierszu zasobu, aby wyświetlić listę.
  2. Na liście kliknij Wyświetl jako i wybierz format, którego chcesz użyć.

    Dostępne formaty zależą od typu danych wybranego zasobu. Możesz zobaczyć jedną lub kilka z tych opcji:

    • Class (Klasa): wyświetla definicję klasy.
    • toString: format ciągu wyświetlanego.
    • Obiekt: wyświetla definicję obiektu (instancji klasy).
    • Tablica:wyświetlanie w formacie tablicy.
    • Znacznik czasu: wyświetla datę i godzinę w formacie rrrr-mm-dd gg:mm:ss.
    • Automatycznie: Android Studio wybiera najlepszy format na podstawie typu danych.
    • Binarna: wyświetla wartość binarną za pomocą zer i jedynek.
    • MeasureSpec: wartość przekazana z elementu nadrzędnego do wybranego elementu podrzędnego. Zobacz MeasureSpec
    • Szesnastkowy:wyświetlanie w formacie szesnastkowym.
    • Typ prosty: wyświetlaj jako wartość liczbową przy użyciu prostego typu danych.
    • Liczba całkowita: wyświetlana jako wartość liczbowa typu Integer.

Aby utworzyć format niestandardowy:

  1. Kliknij prawym przyciskiem myszy wartość zasobu.
  2. Kliknij Wyświetl jako.
  3. Kliknij Utwórz.
  4. Wyświetli się okno Java Data Type Renderers (Renderery typów danych Java). Postępuj zgodnie z instrukcjami podanymi w artykule Java Data type renderers (Renderery typów danych w języku Java).