Android - jak mohu vyšetřovat ANR?

hlasů
121

Existuje způsob, jak zjistit, kde je moje app hodil ANR (Application Neodpovídá). Vzal jsem si pohled na soubor traces.txt in / dat a vidím stopu pro mé žádosti. To je to, co vidím v trasování.

DALVIK THREADS:
main prio=5 tid=3 TIMED_WAIT
  | group=main sCount=1 dsCount=0 s=0 obj=0x400143a8
  | sysTid=691 nice=0 sched=0/0 handle=-1091117924
  at java.lang.Object.wait(Native Method)
  - waiting on <0x1cd570> (a android.os.MessageQueue)
  at java.lang.Object.wait(Object.java:195)
  at android.os.MessageQueue.next(MessageQueue.java:144)
  at android.os.Looper.loop(Looper.java:110)
  at android.app.ActivityThread.main(ActivityThread.java:3742)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:515)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
  at dalvik.system.NativeStart.main(Native Method)

Binder Thread #3 prio=5 tid=15 NATIVE
  | group=main sCount=1 dsCount=0 s=0 obj=0x434e7758
  | sysTid=734 nice=0 sched=0/0 handle=1733632
  at dalvik.system.NativeStart.run(Native Method)

Binder Thread #2 prio=5 tid=13 NATIVE
  | group=main sCount=1 dsCount=0 s=0 obj=0x433af808
  | sysTid=696 nice=0 sched=0/0 handle=1369840
  at dalvik.system.NativeStart.run(Native Method)

Binder Thread #1 prio=5 tid=11 NATIVE
  | group=main sCount=1 dsCount=0 s=0 obj=0x433aca10
  | sysTid=695 nice=0 sched=0/0 handle=1367448
  at dalvik.system.NativeStart.run(Native Method)

JDWP daemon prio=5 tid=9 VMWAIT
  | group=system sCount=1 dsCount=0 s=0 obj=0x433ac2a0
  | sysTid=694 nice=0 sched=0/0 handle=1367136
  at dalvik.system.NativeStart.run(Native Method)

Signal Catcher daemon prio=5 tid=7 RUNNABLE
  | group=system sCount=0 dsCount=0 s=0 obj=0x433ac1e8
  | sysTid=693 nice=0 sched=0/0 handle=1366712
  at dalvik.system.NativeStart.run(Native Method)

HeapWorker daemon prio=5 tid=5 VMWAIT
  | group=system sCount=1 dsCount=0 s=0 obj=0x4253ef88
  | sysTid=692 nice=0 sched=0/0 handle=1366472
  at dalvik.system.NativeStart.run(Native Method)

----- end 691 -----

Jak mohu zjistit, kde je problém? Metody v stopy jsou všechny metody SDK.

Dík.

Položena 01/04/2009 v 07:28
zdroj uživatelem
V jiných jazycích...                            


10 odpovědí

hlasů
107

ANR se stane, když některé dlouhé operace probíhá v „hlavní“ závitem. To je smyčka nitě událost, a je-li obsazeno, může Android nezpracovává žádné další GUI události v žádosti, a tudíž pozvrací se dialog ANR.

Nyní, v trasování jste posta se zdá, že hlavní vlákno, aby se daří dobře, není žádný problém. Je volnoběhu v MessageQueue, čeká na další zpráva přijít. Ve vašem případě, že ANR byl pravděpodobně delší operace, spíše než něco, co zablokoval nit trvale, takže nit události poté, co se operace dokončena, a vaše stopy prošel po ANR.

Odhalování kde chyby ANR stát, je snadné, pokud se jedná o trvalý blok (deadlock získání nějaké zámky například), ale těžší, když je to jen dočasné zpoždění. Za prvé, jít přes váš kód a hledat vunerable spotů a dlouhá provozní operace. Příkladem může být použití zásuvky, zámky, závit spí a další blokující operace v rámci závitu událostí. Měli byste se ujistit, to vše se stalo v oddělených vláknech. Pokud se nic Zdá se problém vyřešit, použijte DDMS a umožňují pohled niti. To ukazuje všechny příze v aplikaci podobné stopy máte. Reprodukovat ANR, a obnovit hlavní vlákno ve stejnou dobu. Že byste měli ukázat přesně, co se děje v době ANR

Odpovězeno 01/04/2009 v 21:59
zdroj uživatelem

hlasů
86

Můžete povolit StrictMode hladiny API 9 a výše.

StrictMode se nejčastěji používá k zachycení náhodnému disk nebo síťový přístup k hlavním vlákně aplikace, kde jsou přijímány UI operace a animace uskuteční. Tím, že hlavní vlákno vaší aplikace reaguje, můžete také zabránit ANR dialogy zobrazovaly uživatelům.

public void onCreate() {
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                           .detectAll()
                           .penaltyLog()
                           .penaltyDeath()
                           .build());
    super.onCreate();
}

pomocí penaltyLog()můžete sledovat výstup adb Logcat, zatímco vy používáte aplikaci vidět porušování jak k nim dochází.

Odpovězeno 29/07/2011 v 10:00
zdroj uživatelem

hlasů
48

Jste zvědaví, která mají za úkol držet UI vlákno. Trasovací soubor vám dává náznak najít úkol. je třeba zkoumat stav každé vlákno

Stav závitu

  • running - spouštění kódu aplikace
  • spaní - tzv Thread.sleep ()
  • monitorovat - čekání na získání zámku monitoru
  • čekat - v Object.wait ()
  • Rodák - vykonávající nativního kódu
  • vmwait - čekání na prostředek VM
  • zombie - vlákno je v procesu umírání
  • init - nit inicializace (neměli byste vidět)
  • začíná - vlákno je asi na začátku (neměli byste vidět jeden)

Zaměřit se na pozastaveno MONITOR stavu. stavu monitoru udává, které vlákno je vyšetřován a suspenduje stav závitu je pravděpodobně hlavním důvodem pro zablokování.

Základní vyšetřovat kroky

  1. Najít „čekání na zámek“
    • najdete stav monitoru "Binder Thread # 15" prio = 5 tid = 75 MONITOR
    • budete mít štěstí, pokud si „čekání na zámek“
    • Příklad: čekání uzamknout <0xblahblah> (a com.foo.A) držena ThreadID = 74
  2. Můžete si všimnout, že „tid = 74“ držet úkol nyní. Takže jít do tid = 74
  3. tid = 74 Možná pozastavené stavu! najít hlavní důvod!

stopa nemusí vždy obsahovat „čekání na zámek“. V tomto případě je těžké najít hlavní důvod.

Odpovězeno 15/07/2014 v 16:03
zdroj uživatelem

hlasů
9

Byl jsem učit androida za posledních několik měsíců, takže jsem daleko od odborníka, ale já jsem opravdu zklamaný s dokumentací o chyb ANR.

Většina doporučení se zdá být zaměřena na jejich odstranění nebo jejich upevnění by slepě hledá prostřednictvím kódu, což je skvělé, ale nemohl jsem najít nic na analýze trasování.

Existují tři věci, které skutečně potřebují hledat s ANR protokoly.

1) zablokování: Je-li vlákno je ve stavu čekání, můžete si prohlédnout podrobnosti zjistit, kdo je to „heldby =“. Většinu času, to bude konat sám od sebe, ale pokud je to v držbě jiném vlákně, to je pravděpodobné, že se špatným znamením. Jít se podívat na toto vlákno a uvidíme, co to je držen. Ty by mohly najít smyčky, což je jasným znamením, že se něco pokazilo. To je docela vzácné, ale je to první bod, protože když se to stane, je to noční můra

2) Hlavní závit Čekání: Pokud je váš hlavní vlákno je ve stavu čekání, zkontrolujte, zda je to v držbě jiném vlákně. To by se nemělo stát, protože vaše UI vlákno by nemělo být držen pozadí nit.

Oba tyto scénáře, znamenat, že budete muset přepracovat svůj kód výrazně.

3) Těžké operace na hlavním tématu: To je nejčastější příčinou chyb ANR, ale někdy jeden z těžší najít a opravit. Podívejte se na hlavní podrobností o závitech. Posunout dolů trasování zásobníku a až uvidíte tříd poznáte (z aplikace). Podívejte se na metody v stopy a zjistit, jestli jste dělat síťových volání DB hovory atd v těchto místech.

A konečně, a omlouvám se za nestydatě zapojíte svůj vlastní kód, můžete použít analyzátor python log jsem napsal na https://github.com/HarshEvilGeek/Android-Log-Analyzer To půjde přes vaše log souborů, otevřené soubory ANR, najít zablokování, zde čeká hlavní téma, najít nezachycené výjimky ve svých protokolech agenta a vytisknout to všechno na obrazovce poměrně snadno číst způsobem. Přečtěte si soubor README (což Chystám se přidat) se naučit, jak ji používat. To mi pomohlo tuny v posledním týdnu!

Odpovězeno 08/08/2014 v 08:14
zdroj uživatelem

hlasů
4

Kdykoli budete analyzovat problémy načasování, ladění často nepomáhá, protože zmrazení aplikaci při zlomu bude tento problém zmizí.

Nejlepším řešením je vložit spoustu protokolování hovorů (Log.XXX ()) do různých nití a zpětná volání dané aplikace a zjistit, kde je zpoždění při. Pokud potřebujete StackTrace vytvořit novou výjimku (jen instanci jeden) a přihlásit jej.

Odpovězeno 18/02/2011 v 21:26
zdroj uživatelem

hlasů
3

Co spouští ANR?

Obecně platí, že systém zobrazí ANR, pokud aplikace nemůže reagovat na vstup uživatele.

V každém případě, ve kterém je vaše aplikace provádí potenciálně zdlouhavé operaci byste neměli vykonávat práci na UI vlákno, ale místo toho vytvořit pracovní podproces a dělat většinu práce tam. To udržuje UI vlákno (který pohání zvláštní události smyčky User Interface) chodu a brání systému v závěru, že váš kód byl zmrazen.

Jak se vyhnout ANR

Android aplikace běžně používán výhradně na jednom vlákně standardně jen „UI vlákna“ nebo „hlavní nit“). To znamená, že něco je aplikace dělá v UI vlákno, které trvá dlouhou dobu k dokončení může vyvolat dialog ANR, protože vaše aplikace není dává sama šanci zvládnout vstupní události nebo se záměrem vysílání.

Proto každá metoda, která běží v uživatelském rozhraní závitu by měl dělat co nejméně práce jako možné v tomto vlákně. Zejména by tyto činnosti měla dělat tak málo, jak je to možné nastavit v klíčových metod životního cyklu, jako onCreate () a onResume (). Potenciálně dlouho běžících operacích, jako například síťové nebo databázové operace, nebo výpočetně náročné výpočty, jako je změna velikosti bitmap by mělo být provedeno v pracovního vlákna (nebo v případě databází činností, přes asynchronní požadavek).

Code: Worker závit s třídou AsyncTask

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    // Do the long-running work in here
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
        }
        return totalSize;
    }

    // This is called each time you call publishProgress()
    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    // This is called when doInBackground() is finished
    protected void onPostExecute(Long result) {
        showNotification("Downloaded " + result + " bytes");
    }
}

Code: Provedení Worker nit

K provedení této pracovní podproces, jednoduše vytvořit instanci a volání execute ():

new DownloadFilesTask().execute(url1, url2, url3);

Zdroj

http://developer.android.com/training/articles/perf-anr.html

Odpovězeno 25/04/2014 v 10:14
zdroj uživatelem

hlasů
1

Musíte se podívat na „čekání na zámek“ v /data/anr/traces.txt souboru

zadejte popis obrázku zde

Pro více informací: Inženýr pro High Performance s nástroji z Android & Play (Google I / O '17)

Odpovězeno 18/05/2017 v 07:27
zdroj uživatelem

hlasů
1

můj problém s ANR, po mnoho práce jsem zjistil, že vlákno volá prostředek, který neexistoval v rozvržení, namísto vrací výjimku, mám ANR ...

Odpovězeno 06/02/2017 v 08:15
zdroj uživatelem

hlasů
0

Zvažte použití ANR-Watchdog knihovnu přesně sledovat a zachytit ANR trasování zásobníku na vysokou úroveň detailů. Poté je můžete odeslat do svého havárii hlášení knihovny. I doporučujeme používat setReportMainThreadOnly()v tomto scénáři. Můžete buď vytvořit aplikace hodit non-fatální výjimku ze zmrazení bodu, nebo aby se aplikace síla ukončit, když ANR stane.

Všimněte si, že standardní ANR zprávy zaslané na vaši Play pro vývojáře konzoli Google často nejsou dostatečně přesné, aby přesně určit problém. To je důvod, proč je potřeba knihovna třetí strany.

Odpovězeno 07/08/2017 v 09:38
zdroj uživatelem

hlasů
0

Základní o @Horyun Lee odpověď jsem napsal malou python skript pomáhá vyšetřovat ANR z traces.txt.

Chyby ANR bude vystupovat jako grafiky podle graphvizpokud máte nainstalovaný grapvhvizna vašem systému.

$ ./anr.py --format png ./traces.txt

PNG vypíše jako níže, pokud tam jsou chyby ANR zjištěné v souboru traces.txt. To je více intuitivní.

zadejte popis obrázku zde

Ukázkový traces.txtsoubor je použit výše, bylo dostat se sem .

Odpovězeno 11/07/2017 v 10:10
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more