Hoppa till innehåll

Archives

  • januari 2022
  • december 2021
  • november 2021
  • oktober 2021
  • september 2021
  • augusti 2021
  • juli 2021

Categories

  • Inga kategorier
Twit Book ClubArticles
Articles

ANR

On oktober 14, 2021 by admin

När UI-tråden i en Android-app blockeras för länge utlöses ett ANR-fel (ApplicationNot Responding). Om appen är i förgrunden visar systemet en dialogruta för användaren, enligt figur 1. ANR-dialogrutan ger användaren möjlighet att tvinga programmet att sluta.

Figur 1. ANR-dialog som visas för användaren

ANR är ett problem eftersom appens huvudtråd, som ansvarar för att uppdatera användargränssnittet, inte kan bearbeta användarens inmatningshändelser eller rita, vilket skapar frustration hos användaren. Mer information om appens huvudtråd finns i Processer och trådar.

En ANR utlöses för din app när något av följande villkor inträffar:

  • Medans din aktivitet är i förgrunden har din app inte svarat på en inmatningshändelse eller BroadcastReceiver (t.ex. tangenttryckning eller beröringshändelser på skärmen) inom 5 sekunder.
  • Medans du inte har en aktivitet i förgrunden har din BroadcastReceiver inte avslutats inom en avsevärd tid.

Om din app upplever ANRs kan du använda vägledningen i den här artikeln för attdiagnostisera och åtgärda problemet.

  • Detektera och diagnostisera problem
  • Androidvitals
  • Diagnostisering av ANR
  • Strict mode
  • Aktivera ANR-dialoger i bakgrunden
  • Traceview
  • Hämta en spårningsfil
  • Lös problemen
  • Långsam kod på huvudtråden
  • IO på huvudtråden
  • Låskonkurrens
  • Dödspärrar
  • Slow broadcast receivers

Detektera och diagnostisera problem

Android erbjuder flera sätt att informera dig om att din app har ett problem och hjälpa dig att diagnostisera det.Om du redan har publicerat din app kan Androidvitals varna dig om att problemet uppstår, och det finns diagnostiska verktyg som hjälper dig att hitta problemet.

Androidvitals

Androidvitals kan hjälpa till att förbättra appens prestanda genom att varna dig viaPlayConsole när din app uppvisar alltför stora ANRs.Android vitals anser att ANR är för höga när en app:

  • uppvisar minst en ANR i minst 0,47 % av sina dagliga sessioner.
  • uppvisar 2 eller fler ANR i minst 0,24 % av sina dagliga sessioner.

En daglig session avser en dag då appen har använts.

För information om hur Google Play samlar in Android-vitaldata, se dokumentationen förPlay Console.

Diagnostisering av ANR

Det finns några vanliga mönster att leta efter vid diagnostisering av ANR:

  1. Appen gör långsamma operationer som involverar I/O på huvudtråden.
  2. Appen gör en lång beräkning på huvudtråden.
  3. Huvudtråden gör ett synkront binderanrop till en annan process och den andra processen tar lång tid på sig att återkomma.
  4. Huvudtråden är blockerad i väntan på ett synkroniserat block för en lång operation som sker på en annan tråd.
  5. Huvudtråden befinner sig i ett dödläge med en annan tråd, antingen i din process eller via ett binderanrop. Huvudtråden väntar inte bara på att en lång operation ska avslutas, utan befinner sig i en dödlägesituation. För mer information, se Deadlock på Wikipedia.

Följande tekniker kan hjälpa dig att ta reda på vilken av dessa orsaker som orsakar dina ANRs.

Strict mode

Användning av StrictMode hjälper dig att hitta oavsiktliga I/O-operationer på huvudtråden medan du utvecklar din app. Du kan använda StrictMode på program- eller aktivitetsnivå.

Aktivera ANR-dialoger i bakgrunden

Android visar ANR-dialoger för appar som tar för lång tid på sig att bearbeta sändningsmeddelandet endast om Visa alla ANR:er är aktiverat i enhetens utvecklaralternativ. Därför visas ANR-dialoger i bakgrunden inte alltid för användaren, men appen kan fortfarande ha prestandaproblem.

Traceview

Du kan använda Traceview för att få en spårning av din körda app medan du går igenom användningsfallen och identifierar de ställen där huvudtråden är upptagen. Information om hur du använder Traceview finns i Profilering med Traceview ochdmtracedump.

Hämta en spårningsfil

Android lagrar spårningsinformation när den upplever en ANR. På äldre operativsystemutgåvor finns det en enda /data/anr/traces.txt-fil på enheten.På nyare operativsystemutgåvor finns det flera /data/anr/anr_*-filer.Du kan få tillgång till ANR-spår från en enhet eller emulator genom att användaAndroid Debug Bridge (adb) som root:

adb rootadb shell ls /data/anradb pull /data/anr/<filename>

Du kan fånga upp en felrapport från en fysisk enhet genom att använda antingen utvecklaralternativet Take bugreport på enheten, eller kommandot adb bugreport på dinutvecklingsmaskin. Mer information finns i Fånga och läsa felrapporter.

Lös problemen

När du har identifierat problemet kan du använda tipsen i det här avsnittet för att lösa vanligt förekommande problem.

Långsam kod på huvudtråden

Identifiera de ställen i din kod där appens huvudtråd är upptagen i mer än 5 sekunder. Leta efter misstänkta användningsfall i din app och försök att reproducera ANR.

Figur 2 visar till exempel en Traceview-tidslinje där huvudtråden är upptagen i mer än 5 sekunder.

Figur 2. Traceview-tidslinje som visar en upptagen huvudtråd

Figur 2 visar oss att det mesta av den felande koden sker i onClick(View)-hanteraren, vilket visas i följandekodexempel:

I det här fallet bör du flytta arbetet som körs i huvudtråden till en arbetstråd. Android Framework innehåller klasser som kan hjälpa till att flytta uppgiften till en arbetstråd. Se Threading on Android för mer information.

IO på huvudtråden

Exekvering av IO-operationer på huvudtråden är en vanlig orsak till långsamma operationer på huvudtråden, vilket kan orsaka ANRs. Det rekommenderas att flytta alla IO-operationer till en arbetstråd, vilket visas i föregående avsnitt.

Några exempel på IO-operationer är nätverks- och lagringsoperationer. Mer information finns i Utföra nätverksoperationer och Spara data.

Låskonkurrens

I vissa scenarier utförs det arbete som orsakar ANR inte direkt på appens huvudtråd. Om en arbetstråd har en låsning på en resurs som huvudtråden behöver för att slutföra sitt arbete kan en ANR inträffa.

Figur 4 visar till exempel en Traceview-tidslinje där det mesta av arbetet utförs på en arbetstråd.

Figur 4. Traceview-tidslinje som visar att arbetet utförs på en arbetstråd

Men om användarna fortfarande upplever ANR bör du titta på statusen för huvudtråden i Android Device Monitor. Vanligtvis är huvudtråden i RUNNABLE-status om den är redo att uppdatera användargränssnittet och är allmänt responsiv.

Men om huvudtråden inte kan återuppta utförandet är den i BLOCKED-status och kan inte svara på händelser. Statusen visas på Android Device Monitor som Monitor eller Wait, enligt figur 5.

Figur 5. Huvudtråd i Monitor-status

Följande spårning visar en apps huvudtråd som är blockerad i väntan på en källa:

Att granska spårningen kan hjälpa dig att hitta koden som blockerar huvudtråden.Följande kod är ansvarig för att hålla låset som blockerar huvudtråden i föregående spårning:

Ett annat exempel är en apps huvudtråd som väntar på ett resultat från en underordnad tråd, vilket visas i följande kod. Observera att användningen av wait() ochnotify() inte är ett rekommenderat mönster i Kotlin, som har sina egna mekanismer för att hantera samtidighet. När du använder Kotlin bör du använda Kotlin-specifika mekanismer om möjligt.

Det finns några andra situationer som kan blockera huvudtråden, inklusive trådar som använder Lock, Semaphore, samt en resurspool (t.ex. en pool av databasanslutningar) eller andra mekanismer för ömsesidig uteslutning (mutex).

Du bör utvärdera de lås som din app håller på resurser i allmänhet, men om du vill undvika ANR bör du titta på de lås som hålls för resurser som huvudtråden behöver.

Se till att låsen hålls så länge som möjligt, eller ännu bättre,utvärdera om appen överhuvudtaget behöver låsningen. Om du använder spärren för att avgöra när du ska uppdatera användargränssnittet baserat på bearbetningen av en arbetstråd, använd mekanismer som onProgressUpdate() och onPostExecute() för att kommunicera mellan arbetstråden och huvudtråden.

Dödspärrar

En dödspärr inträffar när en tråd går in i ett väntande tillstånd på grund av att en nödvändigresurs innehas av en annan tråd, som också väntar på en resurs som innehas av den första tråden. Om appens huvudtråd befinner sig i denna situation är det troligt att ANRs inträffar.

Deadlocks är ett välstuderat fenomen inom datavetenskapen, och det finns algoritmer för att förhindra deadlocks som du kan använda för att undvika deadlocks.

För mer information, se Deadlock andDeadlock preventionalgorithms onWikipedia.

Slow broadcast receivers

Användningar kan reagera på sändningsmeddelanden, t.ex. aktivering eller inaktivering av flygplansläge eller ändring av anslutningsstatus, med hjälp av sändningsmottagare. En ANR uppstår när en app tar för lång tid på sig att behandla meddelandet.

En ANR uppstår i följande fall:

  • En sändningsmottagare har inte avslutat utförandet av sin onReceive()-metod inom en avsevärd tid.
  • En sändningsmottagare anropar goAsync()och misslyckas med att anropa finish() på PendingResult-objektet.

Din app bör endast utföra korta operationer i onReceive()-metoden för en BroadcastReceiver. Om din app kräver mer komplex behandling till följd av ett sändningsmeddelande bör du dock skjuta uppgiften till enIntentService.

Du kan använda verktyg som Traceview för att identifiera om din sändningsmottagare utför långkörande operationer på appens huvudtråd. Figur 6 visar till exempel tidslinjen för en sändningsmottagare som behandlar ett meddelande i huvudtråden i ungefär 100 sekunder.

Figur 6. Traceview-tidslinje som visar BroadcastReceivers arbete på huvudtråden

Detta beteende kan orsakas av att långkörande operationer exekveras på onReceive()-metoden i BroadcastReceiver, vilket visas i följande exempel:

I situationer som dessa rekommenderas det att flytta den långkörande operationen till en IntentService eftersom den använder en arbetstråd för att exekvera sitt arbete. Följande kod visar hur man använder en IntentService för att bearbeta en långsam operation:

Som ett resultat av att använda IntentService exekveras den långsamma operationen på en arbetstråd istället för på huvudtråden. Figur 7visar arbetet som skjutits upp till arbetstråden i tidslinjen Traceview.

Figur 7. Traceview-tidslinje som visar det sändningsmeddelande som behandlas i en arbetstråd

Din sändningsmottagare kan använda goAsync() för att signalera till systemet att det behöver mer tid för att behandla meddelandet. Du bör dock anropa finish() på PendingResult-objektet. Följande exempel visar hur man anropar finish() för att låta systemet återanvända sändningsmottagaren och undvika en ANR:

Och om man flyttar koden från en långsam sändningsmottagare till en annan tråd och använder goAsync() kan man inte åtgärda ANR om sändningen sker i bakgrunden. ANR-tidsgränsen gäller fortfarande.

För mer information om ANR:er, seHålla din app responsiv. Mer information om trådar finns i Trådprestanda.

Lämna ett svar Avbryt svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

Senaste inläggen

  • Homeriska hymner | Hymn 5 : Till Afrodite | Sammanfattning
  • Splash Pads
  • 9 Feng Shui Växter för kontoret 2021 – Betydelse och symbolik
  • Homemade Montreal Steak Spice. Billigare plus att du kontrollerar saltnivån.
  • Vad är dessa kliande knölar på min käklinje och kinder?
  • Deutsch
  • Nederlands
  • Svenska
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語

Arkiv

  • januari 2022
  • december 2021
  • november 2021
  • oktober 2021
  • september 2021
  • augusti 2021
  • juli 2021

Meta

  • Logga in
  • Flöde för inlägg
  • Flöde för kommentarer
  • WordPress.org

Upphovsrätt Twit Book Club 2022 | Tema av ThemeinProgress | Drivs med WordPress