Skip to content

Archives

  • ianuarie 2022
  • decembrie 2021
  • noiembrie 2021
  • octombrie 2021
  • septembrie 2021
  • august 2021
  • iulie 2021

Categories

  • Nicio categorie
Twit Book ClubArticles
Articles

ANRs

On octombrie 14, 2021 by admin

Când firul UI al unei aplicații Android este blocat pentru prea mult timp, se declanșează o eroare „ApplicationNot Responding” (ANR). Dacă aplicația se află în prim-plan, sistemul afișează utilizatorului un dialog, așa cum se arată în figura 1. Dialogul ANR îi oferă utilizatorului posibilitatea de a ieși forțat din aplicație.

Figura 1. Dialogul ANR afișat utilizatorului

ANR-urile reprezintă o problemă deoarece firul principal al aplicației, care este responsabil pentruactualizarea interfeței cu utilizatorul, nu poate procesa evenimentele de introducere a datelor de către utilizator sau să deseneze, provocând frustrare pentru utilizator. Pentru mai multe informații despre firul principal al aplicației, consultați Processes andthreads.

Un ANR va fi declanșat pentru aplicația dvs. atunci când se întâmplă una dintre următoarele condiții:

  • În timp ce activitatea dvs. este în prim-plan, aplicația dvs. nu a răspuns la un eveniment de intrare sau BroadcastReceiver (cum ar fi evenimentele de apăsare a unei taste sau de atingere a ecranului) în decurs de 5 secunde.
  • În timp ce nu aveți o activitate în prim-plan, BroadcastReceiver dvs. nu a terminat de executat în decurs de o perioadă de timp considerabilă.

Dacă aplicația dvs. se confruntă cu ANR-uri, puteți utiliza îndrumările din acest articol pentru adiagnostica și rezolva problema.

  • Detectarea și diagnosticarea problemelor
  • Android vitals
  • Diagnosticarea ANR-urilor
  • Modul strict
  • Activați dialogurile ANR din fundal
  • Traceview
  • Pull a traces file
  • Reparați problemele
  • Cod lent pe firul principal
  • IO pe firul principal
  • Concordanță de blocare
  • Deadlocks
  • Receptoare de difuzare lentă

Detectarea și diagnosticarea problemelor

Android oferă mai multe mijloace de a vă anunța că aplicația dvs. are o problemă și de a vă ajuta să o diagnosticați.Dacă v-ați publicat deja aplicația, Androidvitals vă poate avertiza că apare o problemă și există instrumente de diagnosticare care vă ajută să găsiți problema.

Android vitals

Android vitals vă poate ajuta să îmbunătățiți performanța aplicației dvs. prin alertarea, prin intermediulPlayConsole, atunci când aplicația dvs. prezintă ANR-uri excesive.Android vitals consideră că ANR-urile sunt excesive atunci când o aplicație:

  • Expune cel puțin un ANR în cel puțin 0,47% din sesiunile sale zilnice.
  • Expune 2 sau mai multe ANR-uri în cel puțin 0,24% din sesiunile sale zilnice.

O sesiune zilnică se referă la o zi în care aplicația dvs. a fost utilizată.

Pentru informații despre modul în care Google Play colectează datele vitale Android, consultați documentațiaPlay Console.

Diagnosticarea ANR-urilor

Există câteva modele comune care trebuie căutate atunci când se diagnostichează ANR-urile:

  1. Aplicația efectuează operațiuni lente care implică I/O pe firul principal.
  2. Aplicația efectuează un calcul îndelungat pe firul principal.
  3. Firul principal efectuează un apel binder sincron către un alt proces, iar acel alt proces are nevoie de mult timp pentru a se întoarce.
  4. Firul principal este blocat în așteptarea unui bloc sincronizat pentru o operațiune îndelungată care are loc pe un alt fir.
  5. Firul principal se află într-un blocaj cu un alt fir, fie în procesul dumneavoastră, fie prin intermediul unui apel binder. Firul principal nu este doar în așteptarea finalizării unei operații lungi, ci se află într-o situație de blocaj. Pentru mai multe informații, consultați Deadlock pe Wikipedia.

Următoarele tehnici vă pot ajuta să aflați care dintre aceste cauze provoacă ANR-urile dumneavoastră.

Modul strict

Utilizarea StrictMode vă ajută să găsiți operațiile I/O accidentale pe firul principal în timp ce vă dezvoltați aplicația. Puteți utiliza StrictMode la nivelul aplicației sau al activității.

Activați dialogurile ANR din fundal

Android afișează dialogurile ANR pentru aplicațiile care durează prea mult timp pentru a procesa mesajul de difuzare numai dacă opțiunea Afișați toate ANR-urile este activată în opțiunile de dezvoltare ale dispozitivului. Din acest motiv, dialogurile ANR din fundal nu sunt întotdeauna afișate utilizatorului, dar aplicația ar putea să se confrunte în continuare cu probleme de performanță.

Traceview

Puteți utiliza Traceview pentru a obține o urmă a aplicației care rulează în timp ce parcurgeți cazurile de utilizare și identificați locurile în care firul principal este ocupat. Pentru informațiidespre cum să utilizați Traceview, consultați Profiling with Traceview anddmtracedump.

Pull a traces file

Android stochează informații de urmărire atunci când experimentează un ANR. La versiunile mai vechi ale sistemului de operare, există un singur fișier /data/anr/traces.txt pe dispozitiv.La versiunile mai noi ale sistemului de operare, există mai multe fișiere /data/anr/anr_*.Puteți accesa urmele ANR de pe un dispozitiv sau emulator utilizândAndroid Debug Bridge (adb) ca root:

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

Puteți capta un raport de eroare de pe un dispozitiv fizic utilizând fie opțiunea Take bugreport developer de pe dispozitiv, fie comanda adb bugreport de pe mașina dumneavoastră de dezvoltare. Pentru mai multe informații, consultați Capturarea și citirea rapoartelor de erori.

Reparați problemele

După ce ați identificat problema, puteți utiliza sfaturile din această secțiune pentru a remedia problemele frecvent întâlnite.

Cod lent pe firul principal

Identificați locurile din codul dvs. în care firul principal al aplicației este ocupat pentru mai mult de 5 secunde. Căutați cazurile de utilizare suspecte din aplicația dvs. și încercați săreproduceți ANR.

De exemplu, figura 2 arată o cronologie Traceview în care firul principal este ocupatpentru mai mult de 5 secunde.

Figura 2. Linia de timp Traceview care arată un fir principal ocupat

Figura 2 ne arată că cea mai mare parte a codului incriminat are loc în gestionarul onClick(View), așa cum se arată în următorulexemplu de cod:

În acest caz, ar trebui să mutați activitatea care se execută în firul principal într-un fir de lucru (workerthread). Cadrul Android include clase care pot ajuta la mutarea sarcinii pe un fir de lucru. Consultați Threading on Androidpentru mai multe informații.

IO pe firul principal

Executarea operațiilor IO pe firul principal este o cauză comună a operațiilor lentepe firul principal, care poate cauza ANR-uri. Este recomandat să mutați toate operațiile IO pe un fir de lucru, așa cum se arată în secțiunea anterioară.

Câteva exemple de operații IO sunt operațiile de rețea și de stocare. Pentru mai multeinformații, consultați Efectuarea operațiilor de rețea și Salvarea datelor.

Concordanță de blocare

În unele scenarii, activitatea care cauzează ANR nu este executată direct pe firul principal al aplicației. Dacă un fir lucrător deține un blocaj pe o resursă de care firul principal are nevoie pentru a-și finaliza activitatea, atunci se poate întâmpla o ANR.

De exemplu, figura 4 prezintă o cronologie Traceview în care cea mai mare parte a activității este executată pe un fir lucrător.

Figura 4. Cronologie Traceview care arată activitatea executată pe un fir de lucru

Dar dacă utilizatorii dvs. încă se confruntă cu ANR-uri, ar trebui să vă uitați la starea firului principal în Android Device Monitor. De obicei, firul principal se află în stareaRUNNABLE dacă este gata să actualizeze interfața de utilizator și este, în general, receptiv.

Dar dacă firul principal nu poate relua execuția, atunci se află în starea BLOCKED și nu poate răspunde la evenimente. Starea se afișează pe Android Device Monitor ca Monitor sau Wait, așa cum se arată în figura 5.

Figura 5. Firul principal în starea Monitor

Următoarea urmărire arată un fir principal al unei aplicații care este blocat în așteptarea unei surse:

Revizuirea urmăririi vă poate ajuta să localizați codul care blochează firul principal.Următorul cod este responsabil pentru menținerea blocajului care blochează firul principal din urmărirea anterioară:

Un alt exemplu este un fir principal al unei aplicații care așteaptă un rezultat de la un fir de lucru, așa cum se arată în următorul cod. Rețineți că utilizarea wait() șinotify() nu este un model recomandat în Kotlin, care are propriile mecanisme de gestionare a simultaneității. Atunci când utilizați Kotlin, ar trebui să folosiți, dacă este posibil, mecanismele specifice Kotlin.

Există și alte situații care pot bloca firul principal, inclusiv firele care utilizează Lock, Semaphore, precum și un grup de resurse (cum ar fi un grup de conexiuni la o bază de date) sau alte mecanisme de excludere reciprocă (mutex).

Ar trebui să evaluați încuietorile pe care aplicația dvs. le deține asupra resurselor în general, dar dacă doriți să evitați ANR-urile, atunci ar trebui să vă uitați la încuietorile deținute pentru resursele solicitate de firul principal.

Asigurați-vă că încuietorile sunt menținute pentru o perioadă cât mai mică de timp, sau chiar mai bine,evaluați dacă aplicația are nevoie de această menținere în primul rând. Dacă folosiți blocajul pentru a determina când să actualizați interfața cu utilizatorul pe baza procesării unui fir lucrător,utilizați mecanisme precum onProgressUpdate() și onPostExecute() pentru a comunica între firul lucrător și firul principal.

Deadlocks

Un deadlock apare atunci când un fir intră într-o stare de așteptare deoarece o resursă necesară este reținută de un alt fir, care așteaptă, de asemenea, o resursă reținută de primul fir. Dacă firul principal al aplicației se află în această situație, este probabil să se întâmple ANR-uri.

Deadlocks sunt un fenomen bine studiat în informatică și există algoritmi de prevenire a deadlock-urilor pe care îi puteți folosi pentru a evita deadlocks.

Pentru mai multe informații, consultați Deadlock andDeadlock preventionalgorithms onWikipedia.

Receptoare de difuzare lentă

Aplicațiile pot răspunde la mesajele de difuzare, cum ar fi activarea sau dezactivarea modului avion sau o modificare a stării de conectivitate, prin intermediul receptoarelor de difuzare. Un ANR apare atunci când o aplicație are nevoie de prea mult timp pentru a procesa mesajul de difuzare.

Un ANR apare în următoarele cazuri:

  • Un receptor de difuzare nu a terminat de executat metoda sa onReceive() într-o perioadă de timp considerabilă.
  • Un receptor de difuzare apelează goAsync()și nu reușește să apeleze finish() pe obiectul PendingResult.

Aplicația dvs. ar trebui să efectueze numai operațiuni scurte în metoda onReceive() a unui BroadcastReceiver. Cu toate acestea, dacă aplicația dvs. necesită o prelucrare mai complexă ca urmare a unui mesaj de difuzare, ar trebui să amânați sarcina către un IntentService.

Puteți utiliza instrumente precum Traceview pentru a identifica dacă receptorul dvs. de difuzare execută operații cu execuție lungă pe firul principal al aplicației. De exemplu, figura 6 arată linia de timp a unui receptor de difuzare care procesează un mesaj pe firul principal timp de aproximativ 100 de secunde.

Figura 6. Cronologia Traceview care arată activitatea receptorului de difuzare pe firul principal

Acest comportament poate fi cauzat de executarea unor operații de lungă durată pe metoda onReceive() a BroadcastReceiver, așa cum se arată în următorul exemplu:

În astfel de situații, se recomandă mutarea operației de lungă durată pe un IntentService, deoarece aceasta utilizează un fir de lucru pentru a-și executa activitatea. Următorul cod arată cum se utilizează un IntentService pentru a procesa o operațiune de lungă durată:

Ca urmare a utilizării IntentService, operațiunea de lungă durată este executată pe un fir de lucru în loc de firul principal. Figura 7afișează activitatea amânată pe firul lucrător în cronologia Traceview.

Figura 7. Cronologia Traceview care arată mesajul de difuzare procesat pe un fir de lucru

Receptorul de difuzare poate utiliza goAsync() pentru a semnala sistemului că are nevoie de mai mult timp pentru a procesa mesajul. Cu toate acestea, trebuie să apelați finish() pe obiectul PendingResult. Următorul exemplu arată cum să apelați finish() pentru a permite sistemului să recicleze receptorul de difuzare și pentru a evita un ANR:

Cu toate acestea, mutarea codului de la un receptor de difuzare lent la un alt fir de execuție și utilizarea goAsync() nu va rezolva ANR-ul dacă difuzarea este în fundal. Timeout-ul ANR se aplică în continuare.

Pentru mai multe informații despre ANR-uri, consultațiKeeping your app responsive. Pentru mai multeinformații despre fire de execuție, consultațiPerformanța firelor de execuție.

.

Lasă un răspuns Anulează răspunsul

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

Articole recente

  • Himnele homerice | Imnul 5 : Către Afrodita | Rezumat
  • Plante de stropit
  • 9 plante Feng Shui pentru biroul de birou 2021 – Semnificație și simbolistică
  • Spice pentru friptură de Montreal făcut în casă. Mai puțin costisitor plus că tu controlezi nivelul de sare.
  • Ce sunt aceste umflături cu mâncărimi pe linia maxilarului și pe obraji?
  • Deutsch
  • Nederlands
  • Svenska
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語

Arhive

  • ianuarie 2022
  • decembrie 2021
  • noiembrie 2021
  • octombrie 2021
  • septembrie 2021
  • august 2021
  • iulie 2021

Meta

  • Autentificare
  • Flux intrări
  • Flux comentarii
  • WordPress.org

Copyright Twit Book Club 2022 | Theme by ThemeinProgress | Proudly powered by WordPress