Testning är en viktig del av Android-utveckling, så att du kan stryka ut alla buggar, fel och prestandaproblem som kan lura i din app innan du släpper ut det på allmänheten.
Varje gång du stöter på ett fel genererar Android ett felmeddelande och visar antingen meddelandet som en del av Android Studio Logcat Monitor eller som en dialog på enheten du använder för att testa din app.
Dessa felmeddelanden är vanligen korta och till den punkten, och vid första anblicken kan det inte tyckas allt som är till hjälp. Emellertid innehåller dessa meddelanden faktiskt all information du behöver för att få ditt projekt tillbaka på spår - du behöver bara veta hur man ska dechiffrera dem!
I den här artikeln kommer vi att ta en djupgående titt på de 13 felmeddelanden som du troligen kommer att stöta på när du utvecklar några Android app. Vi granskar vad var och en av dessa felmeddelanden verkligen betyder att du undersöker alla möjliga anledningar till varför du kan stöta på varje fel och, viktigast av allt, dela steg-för-steg-instruktioner om hur du kan lösa dem.
Det finns ett brett spektrum av felmeddelanden som du kan stöta på när du testar din app, allt från allvarliga fel som kommer att få din app att krascha första gången du försöker installera den på en målenhet till mer subtila fel som försämrar programmets prestanda över tiden.
Beroende på vilken typ av fel du stöter på, kommer Android att visa felmeddelandet antingen på enheten du använder för att testa din app eller i Android Studio.
Spottning av felmeddelanden som visas på en fysisk enhet eller AVD är enkelt - du behöver bara vara uppmärksam på alla dialoger som visas på enhetens skärm! Spottfel som visas i Android Studio kan dock vara knepigt, eftersom Logcat Monitor registrerar en stor mängd information, vilket gör det enkelt att missa viktiga felmeddelanden.
Det enklaste sättet att se till att du inte saknar några felmeddelanden är att öppna Logcat Monitor Mångordig dropdown och ställa in den Fel, som kommer att filtrera bort allt utom felmeddelanden.
Det här felet orsakas när Android Studio inte kan generera din R.java Filen är korrekt, och den kan ofta skära upp ur ingenstans - en minut kommer allt att fungera bra, och nästa minut delar varje del av ditt projekt inte samman. För att göra saker värre, när Android Studio möter R.layout
fel, kommer det vanligtvis att flagga alla dina layoutresursfiler som innehåller fel, vilket gör det svårt att veta var du ska börja leta efter källan till felet.
Ofta är den mest effektiva lösningen det enklaste: rengör och bygga om ditt projekt. Välj Bygg> Rengör Projekt vänta några minuter i verktygsfältet i Android Studio och bygg sedan ditt projekt genom att välja Bygg> Ombyggnadsprojekt.
Om en enda ren / ombyggnadscykel inte fungerar, försök att upprepa denna process ett par gånger, eftersom vissa utvecklare har rapporterat positiva resultat efter att ha slutfört flera rena / återuppbyggda cykler i snabb följd.
Om du stöter på det här felet efter att ha flyttat några filer och kataloger runt, är det möjligt att R.layout
fel orsakas av en felaktig matchning mellan Android Studio cache och ditt projekts nuvarande layout. Om du misstänker att detta kan vara fallet, välj sedan Arkiv> Invalidera Caches / Starta om> Invalidera och starta om från Android Studios verktygsfält.
Problem med namnen på dina resurser kan också förhindra R.java Filen skapas korrekt, så kontrollera att du inte har flera resurser med samma namn och att inga av dina filnamn innehåller ogiltiga tecken. Android Studio stöder endast små bokstäver a-z, 0-9, full stops och understreck, och ett enda ogiltigt tecken kan orsaka en R.layout
fel över hela ditt projekt, även om du inte faktiskt använda sig av den här resursen var som helst i ditt projekt!
Om du identifierar och löser ett fel, men Android Studio visar fortfarande R.layout
fel kan du behöva slutföra en ren / återuppbyggnad innan Android Studio registrerar dina ändringar korrekt.
När du sammanställer din app innehåller APK exekverbara bytecode-filer i form av bytecode-filer i Dalvik Executable (DEX). I DEX-specifikationen anges att en enda DEX-fil kan referera högst 65.536 metoder, och om du stöter på För många fält ... fel betyder det att din app har gått över denna gräns. Observera att detta är en begränsning av antalet metoder som ditt projekt referenser, och inte antalet metoder ditt projekt definierar.
Om du stöter på det här felet kan du antingen:
Processen för att möjliggöra multidex-support varierar beroende på vilka versioner av Android ditt projekt stöder.
Om du riktar in Android 5.0 eller senare öppnas det första steget på din modulnivå build.gradle-fil och inställning multiDexEnabled
till Sann
:
android defaultConfig minSdkVersion 21 multiDexEnabled true
Men om din minSdkVersion
är 20 eller lägre, måste du lägga till multiDexEnabled true
attribut och lägg sedan till multidex-supportbiblioteket som ett projektberoende:
beroenden kompilera 'com.android.support:multidex:1.0.1'
Nästa steg beror på huruvida du inte överstyrer Ansökan
klass.
Om ditt projekt åsidosätter Ansökan
klass, öppna sedan ditt Manifest och lägg till följande till
märka:
...
Om ditt projekt inte åsidosätter Ansökan
klass, då måste du förlänga MultiDexApplication
istället:
public class MyApplication utökar MultiDexApplication
Slutligen, om du åsidosätter Ansökan
klass men kan inte ändra basklassen, då kan du aktivera multidex genom att överstyra attachBaseContext ()
metod och ringer MultiDex.install (detta)
, till exempel:
@Override protected void attachBaseContext (Kontextbas) super.attachBaseContext (bas); MultiDex.install (detta);
Om du får ett JDK-fel när du försöker bygga din app betyder det att Android Studio kämpar för att hitta var JDK är installerad på din utvecklingsmaskin.
Så här åtgärdar du detta fel:
Om detta inte löser problemet, navigera du tillbaka till Arkiv> Projektstruktur ...> SDK-plats, och skriv in hela filvägen manuellt för din JDK. Om du inte är säker på var JDK är installerad på din utvecklingsmaskin kan du ta reda på det genom att öppna Terminal (Mac) eller Command Prompt (Windows) och ange följande kommando:
/ Usr / libexec / JAVA_HOME
Medan AVD är bra för att testa din app på ett brett spektrum av olika hårdvaror och programvaror, bör du alltid testa din app på minst en fysisk Android-smarttelefon eller -platta. Android Studio förmåga att känna igen en ansluten Android-enhet är dock berömd och missad.
Om du har anslutit enheten till din utvecklingsmaskin men stöter på en Det gick inte att installera APK meddelande när du försöker installera din APK, eller enheten visas inte ens i Välj Distributionsmål fönstret, försök sedan följande korrigeringar:
Öppna enhetens inställningar, välj sedan Utvecklaralternativ, och se till USB felsökning är aktiverad. Om du inte ser Utvecklaralternativ i inställningar menyn, välj sedan Om telefon och fortsätt tappa Bygga nummer tills a Du är nu en utvecklare Meddelandet visas. Återgå till huvudmenyn inställningar skärm, och du borde hitta det Utvecklaralternativ har lagts till.
Ibland kan din enhet kräva ytterligare tillägg innan den ansluter till din utvecklingsmaskin. Det kan till exempel vara att fråga dig att välja mellan olika lägen eller för att uttryckligen tillåta anslutningen.
Om du utvecklar på Windows måste du ladda ner lämplig OEM USB-drivrutin för din enhet. Om du är en Nexus-användare kan du ladda ner Google USB drivrutin genom Android Studio SDK Manager.
Du hittar ditt projekt minsta SDK i din modulnivå gradle.build-fil och kan kontrollera vilken version av Android som är installerad på din enhet genom att öppna dess inställningar och swiping till Om telefon sektion.
Öppna ett fönster för Terminal eller Kommandotolk och ändra sedan katalog (CD
), så det pekar på din plattform-verktyg fönster, till exempel:
cd / användare / nedladdningar / adt-bundle-mac / sdk / platform-verktyg
Avsluta och starta sedan adb-processen genom att ange följande kommandon, en efter varandra:
./ adb kill-server
./ adb startserver
Om allt annat misslyckas försöker du koppla från och sedan ansluta enheten igen, starta om enheten, starta om Android Studio och, som en absolut sista utväg, starta om din utvecklingsmaskin.
Om du stöter på det här felet när du försöker installera ditt projekt betyder det att målenheten inte har tillräckligt med minne.
Om du försöker installera ditt projekt på en AVD, bör du kolla hur mycket utrymme du har tilldelat detta specifika AVD:
I det här avsnittet beskrivs de olika typerna av minne som du har tilldelat den här AVD. Om några av dessa värden är ovanligt låga bör du öka dem för att bättre reflektera minnet som är tillgängligt för din vanliga Android-smarttelefon eller surfplatta:
Om det inte finns något konstigt om ditt AVD-minne, eller om du försöker installera din app på en fysisk Android-smarttelefon eller -platta, betyder det här felet vanligtvis att din kompilerade app helt enkelt är för stor. En applikation som tar en betydande bit ut av enhetens minne vid installationstiden kommer aldrig att gå bra.
Om du behöver dramatiskt minska storleken på din APK, försök sedan följande tekniker:
Använd ProGuard för att ta bort oanvända klasser, fält, metoder och attribut. För att aktivera ProGuard, öppna din build.gradle-fil på modulnivå och lägg till följande:
buildTypes release // Aktivera ProGuard // minifyEnabled true // Eftersom vi vill minska vår APK-storlek så mycket som möjligt använder jag inställningarna från filen proguard-android-optimize.txt // proguardFiles getDefaultProguardFile ("proguard -android-optimize.txt '),' proguard-rules.pro '
shrinkResources true
till ditt projekt build.gradle-fil.android: tint
och tintMode
, och du kan rotera en bild med android: fromDegrees
, android: toDegrees
, android: pivotX
, och android: pivotY
.Optimera dina bibliotek. Försök att ta bort eventuella onödiga eller minnesintensiva bibliotek från ditt projekt. Om du behöver använda ett stort bibliotek, kontrollera om det finns något sätt att optimera det här biblioteket för mobilmiljön, eftersom extern bibliotekskod ofta inte är skrivet med mobil i åtanke. Du bör också komma ihåg att många bibliotek innehåller en stor mängd lokaliserade strängar. Om din app inte officiellt stöder dessa bibliotek kan du kanske minska storleken på biblioteket genom att säga Gradle att inte inkludera dessa strängar i din kompilerade APK. För att ange vilka språk som din app officiellt stöder, öppna din build.gradle-fil på modulnivå och använd resConfigs
attribut. Till exempel, här specificerar vi att vi bara vill inkludera engelskspråkiga strängar i vårt projekt:
android defaultConfig resConfigs "sv"
Tänk om din APK innehåller en stor mängd innehåll som den enskilda användaren kan ladda ner men aldrig använda. Till exempel har en enhet med en HDD-skärm inte mycket användbarhet för xxxhdpi
tillgångar! Ett av de mest effektiva sätten att minska storleken på din APK är att separera den i flera APK: er, så när användaren hämtar din app får de en APK som bara innehåller koden och resurserna som är meningsfulla för deras specifika enhet. Du hittar mer information om hur du skapar APK: er som är inriktade på olika skärmdensiteter och specifika ABI (program binära gränssnitt) över på den officiella Android-dokumenten.
En ActivityNotFoundException
uppstår när ett samtal till startActivity (Intent)
eller en av dess varianter misslyckas eftersom Aktivitet
kan inte utföra den givna Avsikt
.
Den vanligaste orsaken till en ActivityNotFoundException
glömmer att förklara en aktivitet i ditt manifest, så öppna ditt manifest och kontrollera att du har förklarat alla dina aktiviteter. Du bör också kontrollera att du har deklarerat varje aktivitet korrekt, med antingen ett fullt kvalificerat klassnamn eller ett helt stopp som en stenografi för paketets namn. Till exempel är båda följande giltiga:
Om du inte kan upptäcka några problem med ditt manifest, finns det några andra potentiella orsaker till ActivityNotFoundExceptions
. För det första, om du stöter på det här felet efter att ha flyttat en Aktivitet
klass från ett paket till ett annat, då är det möjligt att du har förvirrat Android Studio och behöver bara rengöra och bygga om ditt projekt.
En ActivityNotFoundException
kan också orsakas om ett fel i målet Aktivitet
laddas inte korrekt. För att kontrollera om det här inträffar i ditt projekt, sätta din avsiktskod inuti ett provtagningsblock:
prova // Din kod här // fånga (ActivityNotFoundException e) e.printStackTrace ();
Kör din ansökan igen och ta en titt på Android Studio's Logcat Monitor för att se om det är fångat några undantag som kan hindra att målaktiviteten skapas. Om så är fallet ska lösningen av dessa fel lösa ActivityNotFoundException
, för.
De ClassCastException
felet är relaterat till Java: s typkonverteringsfunktion, som låter dig kasta variabler av en typ till en annan. Du stöter på a ClassCastException
när du försöker kasta ett objekt till en klass som det inte är en förekomst. Till exempel kommer båda följande kodsekvenser att resultera i a ClassCastException
:
Objekt x = nytt heltal (0); System.out.println ((String) x);
ImageView image = (ImageView) context.findViewById (R.id.button);
Detta felmeddelande innehåller information om linjen som orsakar ClassCastException
fel, så navigera till den här delen av ditt projekt, kolla vilka objekt som kastas där och lösa eventuella felaktigheter.
Om du inte kan upptäcka ett problem med din gjutning, överväg om du nyligen har flyttat några Visningar
runt i dina layoutresursfiler, som vissa användare har rapporterat stöta på a ClassCastException
efter omläggning av deras Visningar
. Om du misstänker att detta kan vara orsaken till din ClassCastException
, sedan berätta för Android Studio att regenerera dina layoutfiler från början, genom att utföra en ren / återuppbyggnad. Detta tvingar Android Studio att korrekt registrera dina senaste layoutändringar, vilket borde lösa ditt ClassCastException
.
I Java, när du förklarar en referensvariabel skapar du faktiskt en pekare på ett objekt. Du kan förklara att ett objekt pekar för närvarande på en okänd data genom att tilldela ett nollvärde till objektets referens. Null-värden kan vara användbara vid kodning av vissa designmönster, men om du stöter på en NullPointerException (NPE), betyder det att du har försökt använda en referens som pekar på ett nullvärde, som om det refererade till ett objekt. Eftersom det inte finns någon kod att exekvera i den plats där denna referens pekar, slutar du med en NPE.
En NPE åtföljs vanligtvis av information om var detta undantag fångades, så Logcat Monitor ska innehålla exakt den raden där detta fel inträffade. Navigera till detta område av ditt projekt och identifiera referensen som är lika med noll. Då måste du hitta den plats där värdet ska ställas in och ställa in det.
De findViewById
Metoden kan också returnera null om den begärda Se
kan inte hittas, så om din NPE förekommer i en rad som innehåller a findViewById
, Kontrollera att du har initierat layouten som innehåller den här Se
. Också vara på utkik efter eventuella stavfel eller stavfel som kan ha krockat in i ditt findViewById
ring, eftersom dessa också kan resultera i en NPE.
För att undvika NPE som uppstår i ditt projekt, se till att alla objekt initieras innan du försöker använda dem och kontrollera alltid att en variabel inte är null innan du begär en metod eller ett fält från det objektet.
Det här är ett fel som visas som en dialog på Android-enheten eller AVD-enheten du använder för att testa din app. De Ansökan svarar inte (ANR) -fel inträffar när appens användargränssnitt fryser och förblir oförsvarligt för användarinmatning i mer än fem sekunder. Det händer vanligtvis eftersom din app försöker utföra långa eller intensiva operationer på Android: s huvudbruksanvisning.
I Android är den viktigaste användargränssnittet ansvarig för att skicka alla användarinmatningshändelser till lämpliga användargränssnitt och för att uppdatera appens användargränssnitt. Den här tråden kan emellertid bara bearbeta en uppgift i taget, så om du blockerar huvudtråden med några långvariga eller intensiva operationer, kommer din användargränssnitt att vara helt oansvarig tills den här uppgiften är klar.
Om du stöter på ett ANR-meddelande när du testar din app, då definitivt måste titta på det arbete du utför på huvudtråden. Om du emellertid inte uttryckligen stöter på det här felet, men märker att din app ibland känns trög eller långsam, så är det en indikation på att du står på gränsen till ett ANR-fel, och än en gång bör du titta på staten av din användargränssnitt.
Att lösa ANR-fel (och nära-ANR-fel) måste du identifiera alla operationer som har potential att springa långsamt, eller som kräver betydande bearbetningseffekt och flytta sedan bort huvudtråden. Du gör detta genom att skapa en arbetstråd där dessa operationer kan utföras med nollrisk för att blockera huvud-UI-tråden.
Det finns flera sätt att skapa ytterligare trådar, men den enklaste lösningen är att använda en AsynTask
, eftersom denna klass redan innehåller sin egen arbetstråd och en onPostExecute ()
återuppringning som du kan använda för att kommunicera med Android: s huvudbruksanvisning.
Men AsyncTasks passar bättre för att utföra korta bakgrundsoperationer, så om du behöver utföra en långvarig operation, ska du använda en Service
eller en IntentService
istället.
Även om du flyttar långvariga och intensiva uppgifter bort från huvudgängan, kommer det att ha störst effekt på din apps prestanda, det är bästa sättet att utföra så lite arbete som möjligt på huvudgränssnittet. Även om du kör en liten mängd onödig kod på huvudtråden kan det påverka appens responsivitet, så när du har flyttat alla dina långvariga och intensiva operationer framgångsrikt bör du titta på om det finns någon kod som du kan Flytta bort huvudgängan.
I Android kan du bara uppdatera ditt användargränssnitt från huvudtråden. Om du försöker komma åt användargränssnitt från någon annan tråd kommer du att stöta på det här felet.
Lös problemet genom att identifiera den del av din bakgrundsuppgift som försöker uppdatera användargränssnittet och flytta den till en runOnUiThread
, till exempel:
runOnUiThread (new Runnable () @Override public void run () // Uppdatera ditt användargränssnitt //);
Alternativt kan du använda en hanterare eller utföra ditt bakgrundsarbete i en AsyncTask, eftersom du kan kommunicera med huvudtråden med hjälp av AsyncTask onPostExecute ()
återuppringningsmetod. Slutligen, om du befinner dig regelbundet att byta mellan tråden, kanske du vill titta på RxAndroid, eftersom det här biblioteket låter dig skapa en ny tråd, schemalägga arbete som ska utföras på den här tråden och sedan posta resultaten till huvudtråden, alla med bara några rader av kod.
Det här undantaget kastas när din app försöker utföra nätverksoperationer på huvudgänget, t.ex. att skicka API-förfrågningar, ansluta till en fjärransluten databas eller hämta en fil. Eftersom nätverksoperationer kan vara tidskrävande och arbetsintensiva, kommer de högst sannolikt att blockera huvudgänget, så Android 3.0 (Honeycomb) och högre kommer att kasta det här felet när du försöker göra en nätverksförfrågan på huvudtråden.
Om du stöter på a NetworkOnMainThreadException
, hitta sedan nätverkskoden som körs på din huvudgänga och flytta den till en separat tråd.
Om du behöver göra vanliga nätverksförfrågningar kanske du vill kolla på Volley, ett HTTP-bibliotek som initierar egna bakgrundsgängor så att alla nätverksförfrågningar utförs som standard av trådtråden.
Det här felet uppstår när du försöker visa en dialog efter att du avslutat aktiviteten. Om du stöter på det här problemet, öppna sedan din aktivitet och se till att du avvisar dialogen ordentligt, genom att ringa avfärda()
i antingen din aktivitet onDestroy ()
eller onPause ()
metod, till exempel:
@Override protected void onDestroy () super.onDestroy (); om (pDialogue! = null) pDialogue.dismiss ();
Det här felet uppstår när din app gör en minnesförfrågan som systemet inte kan uppfylla. Om du stöter på det här felmeddelandet börjar du med att utesluta alla de vanligaste minneshanteringsfel. Kontrollera att du har komma ihåg att avregistrera alla dina mottagare och att du har stoppat alla dina tjänster. se till att du inte håller på referenser i några statiska medlemsvariabler, och att du inte försöker ladda några stora bitmappar.
Om du har uteslutit alla uppenbara orsakerna till en OutOfMemoryError
, då måste du gräva djupare och undersöka exakt hur din app tilldelar minne, eftersom chansen är att det finns några områden där du kan förbättra din apps minneshantering.
Android Studio har ett helt område för att hjälpa dig att analysera din apps minnesanvändning, så börja med att välja Visa> Verktygsfönster från Android Studio-verktygsfältet. Vid denna tidpunkt ser du antingen en Android Monitor eller Android Profiler alternativ, beroende på vilken version av Android Studio du har installerat.
Vi har diskuterat att arbeta med Memory Monitor på den här webbplatsen innan, men eftersom Android Profiler är ett nytt tillägg till Android Studio, låt oss ta en snabb titt på de viktigaste funktionerna.
När du öppnar Android Profiler börjar det automatiskt spela in tre bitar av information.
Eftersom vi är intresserade av hur vår app använder minne, ge Minne avsnitt ett klick, som startar Memory Profiler.
Minnesprofilen består av en tidslinje som visar olika typer av minne som tilldelas av din app, till exempel java, inföding, och stack. Ovanför den här grafen hittar du en rad ikoner som du kan använda för att utlösa olika åtgärder:
Att identifiera de delar av din ansökan som är ansvariga för OutOfMemoryError
, spendera lite tid på att interagera med din app och övervaka hur din apps minnesallokering ändras som svar på olika åtgärder. När du har identifierat den del av ditt projekt som orsakar problemet, spendera lite tid på att granska det för eventuella minnesläckor, liksom eventuella ineffektiviteter i hur det används minne.
I den här artikeln tittade vi på 13 av de felmeddelanden som du troligen kommer att stöta på när du utvecklar för Android. Vi diskuterade alla olika faktorer som kan bidra till dessa fel och de steg du behöver vidta för att lösa dem.
Om du blir plågad av ett felmeddelande som vi inte täckte, bör ditt första steg kopiera / klistra in hela felmeddelandet till Google, eftersom det ofta blir trådar och blogginlägg där människor diskuterar hur man ska lösa detta speciella fel.
Och om du inte hittar någon lösning någonstans på webben kan du alltid nå ut till Android-communityen för hjälp direkt, genom att skicka din fråga till Stack Overflow.
Medan du är här, kolla in några av våra andra inlägg i Android apputveckling!