Android Studio indeholder en debugger, der giver dig mulighed for at gøre følgende og meget mere:
- Vælg en enhed til at debugge din app på.
- Sæt breakpoints i din Java-, Kotlin- og C/C++-kode.
- Undersøg variabler og evaluerer udtryk på køretid.
Denne side indeholder instruktioner til grundlæggende debuggeroperationer. Du kan også finde mere dokumentation i dokumentationen om debugging i IntelliJ IDEA.
- Aktiver debugging
- Start debugging
- Anknyt debuggeren til en kørende app
- Skift debuggertype
- Brug systemloggen
- Skriv logmeddelelser i din kode
- Se systemloggen
- Arbejd med breakpoints
- Visning og konfiguration af breakpoints
- Debug-vinduets rammer
- Inspicer variabler
- Tilføj watchpoints
- Visning og ændring af visningsformatet for ressourceværdier
Aktiver debugging
Hvor du kan begynde at debugge, skal du forberede dig på følgende måde:
- Aktiver debugging på din enhed:
Hvis du bruger emulatoren, er dette aktiveret som standard. Men for en tilsluttet enhed skal du aktivere debugging i enhedens udviklerindstillinger.
- Kør en build-variant, der kan debugges:
Du skal bruge en build-variant, derinkluderer
debuggable true
i build-konfigurationen. Normalt kan du bare vælge standardvarianten “debug”, som er inkluderet i alle Android Studio-projekter (selv om den ikke er synlig i filenbuild.gradle
). Men hvis du definerer nye build-typer, der skal kunne debugges, skal du tilføje `debuggable true` til build-typen:android { buildTypes { customDebugType { debuggable true ... } }}
Denne egenskab gælder også for moduler med C/C++-kode. (Egenskaben
jniDebuggable
bruges ikke længere.)Hvis din app afhænger af et biblioteksmodul, som du også ønsker at debugge, skal dette bibliotek også pakkes med
debuggable true
, så det beholder sine debug-symboler.For at sikre, at de debuggable varianter af dit app-projekt modtager den debuggable variant af et biblioteksmodul, skal du sørge for at udgive ikke-standardiserede versioner af dit bibliotek.
Start debugging
Du kan starte en debugging-session på følgende måde:
- Sæt nogle breakpoints i app-koden.
- I værktøjslinjen skal du vælge en enhed til at debugge din app på i rullemenuen for målenhed.
Hvis du ikke har konfigureret nogen enheder, skal du enten tilslutte en enhed via USB eller oprette en AVD for at bruge Android-emulatoren.
- I værktøjslinjen skal du klikke på Debug .
Hvis du får vist en dialogboks, der spørger, om du vil “skifte fra Kør til fejlfinding”, betyder det, at din app allerede kører på enheden, og at den skal genstartes for at kunne begynde fejlfinding. Hvis du hellere vil beholde den samme instans af appen kørende, skal du klikke på Annuller debugning og i stedet knytte debuggeren til en kørende app.
Ellers opbygger Android Studio en APK, underskriver den med en debugnøgle, installerer den på den valgte enhed og kører den. Hvis du tilføjer C og C++-kode til dit projekt, kører Android Studio også LLDB-debuggeren i vinduet Debug for at debugge din native kode.
- Hvis Debug-vinduet ikke er åbent, skal du vælge Vis > Værktøjsvinduer > Debug (eller klikke på Debug i værktøjsvinduets bjælke) og derefter klikke på fanen Debugger, som vist i figur 1.
Figur 1. Debugger-vinduet, der viser den aktuelle tråd og objekttræet for en variabel
Anknyt debuggeren til en kørende app
Hvis din app allerede kører på din enhed, kan du starte debugging uden at genstarte din app på følgende måde:
- Klik på Tilknyt debugger til Android-processen .
- I dialogboksen Vælg proces skal du vælge den proces, du vil knytte debuggeren til.
Hvis du bruger en emulator eller en rooted enhed, kan du markere Vis alle processer for at få vist alle processer.
I rullemenuen Brug Android Debugger-indstillinger fra kan du vælge en eksisterende kør/fejlsøgningskonfiguration. (For C og C++-kode giver dette dig mulighed for at genbruge LLDB-startkommandoerne, LLDB-post-attach-kommandoerne og symbolkatalogerne i en eksisterende konfiguration). Hvis du ikke har en eksisterende run/debug-konfiguration, skal du vælge Create New (Opret ny). Dette valg aktiverer rullemenuen Debug Type, hvor du kan vælge en anden debugtype. Som standard bruger Android Studio den automatiske debugtype til at vælge den bedste debuggermulighed for dig, baseret på om dit projekt indeholder Java- eller C/C++-kode.
- Klik på OK.
Debug-vinduet vises.
Bemærk: Android Studio-debuggeren og garbage collector er løst integreret. Den virtuelle Android-maskine garanterer, at ethvert objekt, som debuggeren er bekendt med, ikke bliver skraldet, før debuggeren afbryder forbindelsen. Dette kan resultere i en ophobning af objekter over tid, mens debuggeren er tilsluttet. Hvis debuggeren f.eks. ser en kørende tråd, bliver det tilknyttede Thread
objekt ikke skraldet, før debuggeren afbryder forbindelsen, selv om tråden er afsluttet.
Skift debuggertype
Da der kræves forskellige debuggerværktøjer for at debugge Java/Kotlin-kode og C/C++-kode, giverAndroid Studio-debuggeren dig mulighed for at vælge, hvilken debuggertype du vil bruge. Som standard bestemmer Android Studio, hvilken debugger der skal bruges, på baggrund af hvilke sprog den registrerer i dit projekt (med typenAuto debugger). Du kan dog manuelt vælge debuggeren i debugkonfigurationen (klik på Run > EditConfigurations) eller i den dialogboks, der vises, når du klikker på Run > Attach debugger to Androidprocess.
De tilgængelige debug-typer omfatter følgende:
Auto Vælg denne debug-type, hvis du vil have Android Studio til automatisk at vælge den bedste indstilling til den kode, du debugger. Hvis du f.eks. har C eller C++-kode i dit projekt, bruger Android Studio automatisk debug-typen Dual. Ellers bruger Android Studio Java-debugtypen. Java Vælg denne debug-type, hvis du kun vil debugge kode, der er skrevet i Java eller Kotlin – Java-debuggeren ignorerer eventuelle breakpoints eller ure, du har angivet i din native kode. Native (kun tilgængelig med C/C++-kode) Vælg denne debug-type, hvis du kun vil bruge LLDB til at debugge din kode. Når du bruger denne debugtype, er Java-debugger-sessionsvisningen ikke tilgængelig. Som standard inspicerer LLDB kun din native kode og ignorerer breakpoints i din Java-kode. Hvis du også ønsker at debugge din Java-kode, skal du skifte til enten Auto eller Dual debug type.
Native debugging fungerer kun på enheder, der opfylder følgende krav:
-
Enheden understøtter
run-as
.For at kontrollere, om enheden understøtter
run-as
, skal du køre følgende kommando på den ADB-shell, der er tilsluttet enheden:run-as your-package-name pwd
Erstat
your-package-name
med din app’s pakkenavn. Hvis enheden understøtterrun-as
, bør kommandoen vende tilbage uden fejl. -
Enheden har
ptrace
aktiveret.For at kontrollere, om
ptrace
er aktiveret, skal du køre følgende kommando på ADB-shell’en, der er tilsluttet din enhed:sysctl kernel.yama.ptrace_scope
Hvis
ptrace
er aktiveret, vil kommandoen udskrive værdien0
eller enunknown key
fejl. Hvisptrace
ikke er aktiveret, vil den udskrive en anden værdi end0
.
Dual (kun tilgængelig med C/C++-kode) Vælg denne fejlsøgningstype, hvis du vil skifte mellem fejlsøgning af både Java- og indfødt kode. Android Studio knytter både Java-debuggeren og LLDB til din app-proces, én til Java-debuggeren og én til LLDB, så du kan inspicere breakpoints i både din Java- og native kode uden at genstarte din app eller ændre din debugkonfiguration.
I figur 2 kan du bemærke de to faner til højre for Debug-vinduets titel. Da appen har både Java- og C++-kode, er den ene fane til fejlsøgning af den native kode og den anden til fejlsøgning af Java-kode, som angivet med -java.
Figur 2. Fane til fejlfinding af indfødt kode og fane til fejlfinding af Java-kode
Bemærk: Hvis du fejlfinding af indfødt kode, der er optimeret af compileren, kan du få følgende advarselsmeddelelse: This function was compiled with optimizations enabled. Some debugger features may not be available
. Når du bruger optimeringsflag, f.eks. -O
-flag, foretager compileren ændringer i din kompilerede kode for at få den til at køre mere effektivt. Dette kan medføre, at debuggeren rapporterer uventede eller forkerte oplysninger, fordi det er vanskeligt for debuggeren at mappe den optimerede kompilerede kode tilbage til den oprindelige kildekode. Af denne grund bør du deaktivere compileroptimeringer, mens du debugger din native kode.
Brug systemloggen
Systemloggen viser systemmeddelelser, mens du debugger din app. Disse meddelelser omfatter oplysninger fra apps, der kører på enheden. Hvis du vil bruge systemloggen til at debugge din app, skal du sørge for, at din kode skriver logmeddelelser og udskriver stacktrace for undtagelser, mens din app er i udviklingsfasen.
Skriv logmeddelelser i din kode
Du kan skrive logmeddelelser i din kode ved at bruge Log
-klassen. Logmeddelelser hjælper dig med at forstå eksekveringsflowet ved at opsamle systemets fejlfindingsoutput, mens du interagerer med din app. Logmeddelelser kan fortælle dig, hvilken del af dit program der fejlede. Du kan finde flere oplysninger om logføring i Skriv og visning af logfiler.
Det følgende eksempel viser, hvordan du kan tilføje logmeddelelser for at fastslå, om tidligere tilstandsoplysninger er tilgængelige, når din aktivitet starter:
Under udviklingen kan din kode også fange undtagelser og skrive staksporet til systemloggen:
Bemærk: Fjern debug-logmeddelelser og staksporet udskriftsopkald fra din kode, når du er klar til at offentliggøre din app. Det kan du gøre ved at indstille et DEBUG
flag og placere debug-logmeddelelser i betingede sætninger.
Se systemloggen
Du kan se og filtrere debug- og andre systemmeddelelser i Logcat-vinduet. Du kan f.eks. se meddelelser, når der sker garbage collection, eller meddelelser, som du tilføjer til din app med Log
-klassen.
Hvis du vil bruge Logcat, skal du starte fejlfinding og vælge fanen Logcat på den nederste værktøjslinje, som vist i figur 3.
Figur 3. Logcat-vindue med filterindstillinger
For en beskrivelse af logcat og dets filtreringsmuligheder, se Skriv og vis logfiler med Logcat.
Arbejd med breakpoints
Android Studio understøtter flere typer breakpoints, derudløser forskellige debugginghandlinger. Den mest almindelige type er et linjebrydepunkt, der sætter afviklingen af din app på pause ved en bestemt kodelinje. Mens du holder pause, kan du undersøge variabler, evaluere udtryk og derefter fortsætte udførelsen linje for linje for at finde årsagerne til kørselsfejl.
For at tilføje et linjebrydepunkt skal du gøre følgende:
- Find den kodelinje, hvor du vil holde pause i udførelsen, og klik derefter enten på den venstre rille langs den pågældende kodelinje, eller placer fluebenet på linjen, og tryk på Control+F8 (på Mac, Command+F8).
- Hvis din app allerede kører, behøver du ikke at opdatere den for at tilføje pausepunktet – du skal blot klikke på Vedhæft debugger til Android-processen . Ellers skal du starte debugging ved at klikke på Debug .
Figur 3. Der vises en rød prik ud for linjen, når du indstiller et breakpoint
Når din kodeudførelse når breakpointet,holder Android Studio en pause i udførelsen af din app. Du kan derefterbruge værktøjerne i fanen Debugger til at identificere appens tilstand:
-
For at undersøge objekttræet for en variabel skal du udvide den i visningen Variables (Variabler). Hvis visningen Variabler ikke er synlig, skal du klikke på Gendan visning af variabler .
-
For at evaluere et udtryk på det aktuelle udførelsespunkt skal du klikke på Evaluerer udtryk .
-
For at gå videre til den næste linje i koden (uden at indtaste en metode) skal du klikke på Step Over .
-
For at gå videre til den første linje inde i et metodekald skal du klikke på Step Into .
-
For at gå videre til den næste linje uden for den aktuelle metode skal du klikke på Step Out .
-
For at fortsætte med at køre programmet normalt skal du klikke på Resume Program .
Hvis dit projekt bruger nogen native kode, knytter Auto debug-typen som standard både Java-debuggeren og LLDB til din app som to separate processer, så du kan skifte mellem at inspicere Java- og C/C++-brydepunkter uden at genstarte din app eller ændre indstillingerne.
Bemærk: For at Android Studio kan registrere brydepunkter i din C- eller C++-kode, skal du bruge en debug-type, der understøtter LLDB, f.eks. Auto, Native eller Dual. Du kan ændre den debug-type, som Android Studio bruger, ved at redigere din debug-konfiguration. Du kan læse mere om de forskellige debug-typer i afsnittet om brug af andre debug-typer.
Når Android Studio distribuerer din app til målenheden, åbnes vinduet Debug med en faneblad eller debug-sessionsvisning for hver debuggerproces, som vist i figur 4.
Figur 4. Debugging af native kode ved hjælp af LLDB
- Android Studio skifter til fanen <din-modul>, når LLDB-debuggeren støder på et breakpoint i din C/C++-kode. Fanerne Frames, Variables og Watches er også tilgængelige og fungerer præcis som de ville gøre, hvis du debuggede Java-kode. Selv om ruden Threads ikke er tilgængelig i LLDB-sessionsvisningen, kan du få adgang til dine app-processer ved hjælp af rullelisten i ruden Frames. Du kan få mere at vide om disse ruder i afsnittene om, hvordan du debugger vinduesrammer og inspicerer variabler.
Bemærk: Mens du inspicerer et breakpoint i din native kode, suspenderer Android-systemet den virtuelle maskine, der kører din app’s Java-bytecode. Det betyder, at du ikke kan interagere med Java-debuggeren eller hente nogen tilstandsinformationer fra din Java-debuggersession, mens du inspicerer et breakpoint i din native kode.
- Android Studio skifter til fanen <din-modul>-java, når Java-debuggeren støder på et breakpoint i din Java-kode.
- Ved debugging med LLDB kan du bruge LLDB-terminalen i LLDB-sessionsvisningen til at sende kommandolinjeindstillinger til LLDB. Hvis du har visse kommandoer, som du gerne vil have LLDB til at udføre, hver gang du starter debugging af din app, enten lige før eller lige efter at debuggeren knytter sig til din app-proces, kan du tilføje disse kommandoer til din debugkonfiguration.
Mens du debugger C/C++-kode, kan du også indstille særlige typer af breakpoints, kaldet watchpoints, som kan suspendere din app-proces, når din app interagerer med en bestemt blok af hukommelse. Hvis du vil vide mere, skal du læse afsnittet om, hvordan du tilføjer overvågningspunkter.
Visning og konfiguration af breakpoints
Hvis du vil se alle breakpoints og konfigurere indstillinger for breakpoints, skal du klikke på Vis breakpoints i venstre side af Debug-vinduet. Vinduet Breakpoints vises, som vist i figur 5.
Figur 5. Vinduet Breakpoints viser en liste over alle de aktuelle breakpoints og indeholder adfærdsindstillinger for hvert
I vinduet Breakpoints kan du aktivere eller deaktivere hvert breakpoint fra listen til venstre. Hvis et breakpoint er deaktiveret, sætter Android Studio ikke din app på pause, når den rammer det pågældende breakpoint. Vælg et breakpoint på listen for at konfigurere dets indstillinger. Du kan konfigurere et breakpoint til at være deaktiveret i første omgang og få systemet til at aktivere det, når et andet breakpoint er ramt. Du kan også konfigurere, om et breakpoint skal deaktiveres, efter at det er ramt. Hvis du vil indstille et breakpoint for en undtagelse, skal du vælge Exception Breakpoints på listen over breakpoints.
Debug-vinduets rammer
I Debugger-vinduet kan du i ruden Frames inspicere den stakramme, der forårsagede, at det aktuelle breakpoint blev ramt. Dette giver dig mulighed for at navigere og undersøge stakrammen og også inspicere listen over tråde i din Android-app. Hvis du vil vælge en tråd, skal du bruge rullemenuen trådvælger og se dens stack frame. Hvis du klikker på elementerne i rammen, åbnes kilden i editoren. Du kan også tilpasse trådpræsentationen og eksportere stakrammen som beskrevet i vejledningen Vinduesrammer.
Inspicer variabler
I vinduet Debugger giver ruden Variabler dig mulighed for at inspicere variabler, når systemet stopper din app på et breakpoint, og du vælger en ramme fra ruden Rammer. I ruden Variabler kan du også evaluere ad hoc-udtryk ved hjælp af statiske metoder og/eller variabler, der er tilgængelige i den valgte ramme.
Ruden Vagter giver en lignende funktionalitet, bortset fra at udtryk, der tilføjes til ruden Vagter, fortsætter mellem debugging-sessioner. Du bør tilføje ure for variabler og felter, som du ofte har adgang til, eller som giver en tilstand, der er nyttig for den aktuelle debugging-session. Ruderne Variabler og Vagter vises som vist i figur 5.
Følg disse trin for at tilføje en variabel eller et udtryk til listen Vagter:
- Begynd debugging.
- I ruden Watches skal du klikke på Tilføj .
- I det tekstfelt, der vises, skal du skrive navnet på den variabel eller det udtryk, du vil overvåge, og derefter trykke på Enter.
Hvis du vil fjerne et element fra listen Overvågninger, skal du markere elementet og derefter klikke på Fjern .
Du kan ændre rækkefølgen af elementerne på listen Overvågninger ved at markere et element og derefter klikke på Op eller Ned .
Figur 6. Ruderne Variabler og Watches i vinduet Debugger
Tilføj watchpoints
Når du debugger C/C++-kode, kan du indstille særlige typer af breakpoints, kaldet watchpoints, der kan suspendere din app-proces, når din app interagerer med en bestemt blok af hukommelse. Hvis du f.eks. indstiller to pointere til en blok af hukommelse og tildeler et overvågningspunkt til den, udløser brugen af en af pointerne til at få adgang til den pågældende blok af hukommelse overvågningspunktet.
I Android Studio kan du oprette et overvågningspunkt under kørslen ved at vælge en bestemt variabel, men LLDB tildeler kun overvågningspunktet til den blok af hukommelse, som systemet tildeler den pågældende variabel, og ikke til selve variablen. Dette er anderledes end at tilføje en variabel til vinduet Watches, som gør det muligt at observere værdien af en variabel, men ikke at suspendere din app-proces, når systemet læser eller ændrer dens værdi i hukommelsen.
Bemærk: Når din app-proces afslutter en funktion, og systemet deallokerer sine lokale variabler fra hukommelsen, skal du omtildele eventuelle overvågningspunkter, du har oprettet for disse variabler.
For at indstille et overvågningspunkt skal du opfylde følgende krav:
- Din fysiske målenhed eller emulator bruger en x86- eller x86_64-CPU. Hvis din enhed bruger en ARM-CPU, skal du tilpasse grænsen for din variabels adresse i hukommelsen til enten 4 bytes for 32-bit processorer eller 8 bytes for 64-bit processorer. Du kan justere en variabel i din native kode ved at angive
__attribute__((aligned(num_bytes)))
i variabelafkortningen, som vist nedenfor:// For a 64-bit ARM processorint my_counter __attribute__((aligned(8)));
- Du har allerede tildelt tre eller færre watchpoints. Android Studio understøtter kun op til fire watchpoints på x86- eller x86_64-målenheder. Andre enheder understøtter muligvis færre watchpoints.
Bemærk: Når du debugger din app med 32-bit ARM ABI’er, kan det medføre et nedbrud, hvis du tilføjer et watchpoint eller svæver over variabler i koden for at undersøge deres værdier. Som en løsning skal du debugge ved hjælp af 64-bit ARM-, x86- eller x86_64-binære filer som en løsning. Dette problem vil blive rettet i en kommende Android Studio-udgave.
Hvis du opfylder ovenstående krav, kan du tilføje et overvågningspunkt på følgende måde:
- Mens din app er suspenderet på et breakpoint, skal du navigere til ruden Variables (Variabler) i din LLDB-sessionsvisning.
-
Højreklik på en variabel, der optager den blok af hukommelse, som du vil spore, og vælg Tilføj overvågningspunkt. En dialogboks til at konfigurere dit overvågningspunkt vises, som vist i figur 7.
Figur 7. Tilføjelse af et overvågningspunkt til en variabel i hukommelsen
- Konfigurer dit overvågningspunkt med følgende indstillinger:
- Aktiveret: Du kan fravælge denne indstilling, hvis du vil bede Android Studio om at ignorere watchpointet for øjeblikket. Android Studio gemmer stadig dit watchpoint, så du kan få adgang til det senere i din debug-session.
- Suspender: Som standard suspenderer Android-systemet din app-proces, når den får adgang til en blok af hukommelse, som du tildeler et watchpoint. Du kan fravælge denne indstilling, hvis du ikke ønsker denne opførsel – dette afslører yderligere indstillinger, som du kan bruge til at tilpasse opførslen, når systemet interagerer med dit overvågningspunkt: Log besked til konsollen og Fjern, når du bliver ramt.
- Adgangstype: Vælg, om din app skal udløse dit overvågningspunkt, når den forsøger at læse eller skrive til den blok af hukommelse, som systemet allokerer til variablen. Hvis du vil udløse dit overvågningspunkt ved enten læsning eller skrivning, skal du vælge Alle.
- Klik på Udført.
Hvis du vil se alle dine watchpoints og konfigurere indstillingerne for watchpoints, skal du klikke på Vis breakpoints i venstre side af Debug-vinduet. Dialogboksen Breakpoints vises, som vist i figur 8.
Figur 8. Dialogboksen Breakpoints viser dine aktuelle watchpoints og indeholder adfærdsindstillinger for hvert enkelt
Når du har tilføjet dit watchpoint, skal du klikke på Resume Program i venstre side af Debug-vinduet for at genoptage din app-proces. Hvis din app forsøger at få adgang til en blok af hukommelse, som du har indstillet et overvågningspunkt til, suspenderer Android-systemet som standard din app-proces, og et overvågningspunkt-ikon vises ved siden af den kodelinje, som din app sidst udførte, som vist i figur 9.
Figur 9. Android Studio viser den kodelinje, som din app udfører lige før udløsning af et watchpoint
Visning og ændring af visningsformatet for ressourceværdier
I fejlfindingstilstand kan du se ressourceværdier og vælge et andet visningsformat for variabler i din Java-kode. Når fanen Variabler vises, og en ramme er valgt, skal du gøre følgende:
- Højreklik på et vilkårligt sted på en ressourcelinje på listen Variabler for at få vist rullelisten.
- Vælg Vis som på rullelisten, og vælg det format, du vil bruge.
De tilgængelige formater afhænger af datatypen for den ressource, du har valgt. Du kan få vist en eller flere af følgende muligheder:
- Klasse:
- tilString: Viser klassedefinitionen.
- tilString: Visning af strengformat.
- Objekt:
- : Viser objektdefinitionen (en instans af en klasse).
- Array: Viser objektdefinitionen (en instans af en klasse): Vises i et array-format.
- Timestamp: Vises i et array-format.
- Timestamp: Vis dato og klokkeslæt som følger: yyyy-mm-dd hh:mm:ss.
- Auto: Android Studio vælger det bedste format ud fra datatypen.
- Binært: Vis en binær værdi ved hjælp af nuller og ettaller.
- MeasureSpec: Den værdi, der er overført fra den overordnede til det valgte barn. Se
MeasureSpec
. - Hex: Vises som en hexadecimal værdi.
- Primitive: Visning som en numerisk værdi ved hjælp af en primitiv datatype.
- Integer: Visning som en numerisk værdi ved hjælp af en primitiv datatype.
- Vis en numerisk værdi af typen
Integer
.
Du kan oprette et brugerdefineret format (datatype-renderer) som følger: