Apakah ada cara untuk mengetahui di mana aplikasi saya melemparkan PPA (Aplikasi Tidak Menanggapi). Saya melihat file traces.txt di / data dan saya melihat jejak untuk aplikasi saya. Inilah yang saya lihat di jejak.
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 -----
Bagaimana saya bisa mengetahui di mana masalahnya? Metode dalam penelusuran adalah semua metode SDK.
Terima kasih.
android
performance
android-anr-dialog
hilangInTransit
sumber
sumber
android.os.MessageQueue.nativePollOnce(Native Method)
. Bisakah saya mengabaikannya dengan aman?Jawaban:
ANR terjadi ketika beberapa operasi lama berlangsung di utas "utama". Ini adalah utas loop acara, dan jika sibuk, Android tidak dapat memproses acara GUI lebih lanjut dalam aplikasi, dan karenanya memunculkan dialog PPA.
Sekarang, dalam jejak yang Anda posting, utas utama tampaknya baik-baik saja, tidak ada masalah. Itu idle di MessageQueue, menunggu pesan lain masuk. Dalam kasus Anda ANR kemungkinan operasi yang lebih lama, daripada sesuatu yang memblokir utas secara permanen, sehingga utas peristiwa pulih setelah operasi selesai, dan penelusuran Anda dilacak setelah PPA.
Mendeteksi di mana PPA terjadi mudah jika itu adalah blok permanen (kebuntuan mendapatkan beberapa kunci misalnya), tetapi lebih sulit jika itu hanya penundaan sementara. Pertama, periksalah kode Anda dan cari tempat-tempat yang vunerable dan operasi yang berjalan lama. Contohnya termasuk menggunakan soket, kunci, tidur ulir, dan operasi pemblokiran lainnya dari dalam utas acara. Anda harus memastikan ini semua terjadi di utas terpisah. Jika tidak ada masalah, gunakan DDMS dan aktifkan tampilan utas. Ini menunjukkan semua utas dalam aplikasi Anda mirip dengan jejak yang Anda miliki. Reproduksi ANR, dan segarkan utas utama secara bersamaan. Itu harus menunjukkan dengan tepat apa yang terjadi pada saat PPA
sumber
Anda dapat mengaktifkan StrictMode di API level 9 ke atas.
sumber
Anda bertanya-tanya tugas mana yang memegang Thread UI. File jejak memberi Anda petunjuk untuk menemukan tugas. Anda perlu menyelidiki keadaan setiap utas
Keadaan utas
Fokus pada SUSPENDED, MONITOR state. Status monitor mengindikasikan thread mana yang diselidiki dan status thread yang DITANGGUNG mungkin merupakan alasan utama kebuntuan.
Langkah-langkah investigasi dasar
trace tidak selalu mengandung "waiting to lock". dalam hal ini sulit untuk menemukan alasan utama.
sumber
- waiting to lock an unknown object
di dalam"HeapTaskDaemon" daemon prio=5 tid=8 Blocked
. Apa artinya seseorang dapat membantu?Saya sudah belajar android selama beberapa bulan terakhir, jadi saya jauh dari ahli, tapi saya benar-benar kecewa dengan dokumentasi ANR.
Sebagian besar saran tampaknya diarahkan untuk menghindari mereka atau memperbaikinya dengan melihat secara membabi buta melalui kode Anda, yang bagus, tetapi saya tidak dapat menemukan apa pun dalam menganalisis jejak.
Ada tiga hal yang benar-benar perlu Anda cari dengan log ANR.
1) Deadlock: Ketika sebuah thread berada dalam status WAIT, Anda dapat melihat rincian untuk menemukan siapa itu "dipegang =". Sebagian besar waktu, itu akan dipegang dengan sendirinya, tetapi jika dipegang oleh utas lain, itu mungkin merupakan tanda bahaya. Pergi melihat utas itu dan lihat apa yang dipegangnya. Anda mungkin menemukan lingkaran, yang merupakan pertanda jelas bahwa ada sesuatu yang salah. Ini sangat jarang, tetapi ini adalah poin pertama karena ketika itu terjadi, itu adalah mimpi buruk
2) Utas utama Menunggu: Jika utas utama Anda dalam status TUNGGU, periksa apakah utas dimiliki oleh utas lainnya. Ini seharusnya tidak terjadi, karena utas UI Anda seharusnya tidak dipegang oleh utas latar belakang.
Kedua skenario ini, berarti Anda perlu mengolah kode Anda secara signifikan.
3) Operasi berat pada utas utama: Ini adalah penyebab paling umum dari PPA, tetapi terkadang salah satu yang lebih sulit ditemukan dan diperbaiki. Lihatlah detail utas utama. Gulir ke bawah jejak tumpukan dan sampai Anda melihat kelas yang Anda kenali (dari aplikasi Anda). Lihatlah metode dalam penelusuran dan cari tahu apakah Anda melakukan panggilan jaringan, panggilan db, dll di tempat-tempat ini.
Akhirnya, dan saya minta maaf karena tanpa malu memasukkan kode saya sendiri, Anda dapat menggunakan penganalisis log python yang saya tulis di https://github.com/HarshEvilGeek/Android-Log-Analyzer Ini akan melalui file log Anda, buka file ANR, cari kebuntuan, temukan utas utama yang menunggu, temukan pengecualian yang tidak tertangkap dalam log agen Anda dan cetak semuanya di layar dengan cara yang relatif mudah dibaca. Baca file ReadMe (yang akan saya tambahkan) untuk mempelajari cara menggunakannya. Ini membantu saya satu ton di minggu terakhir!
sumber
Setiap kali Anda menganalisis masalah waktu, debugging sering kali tidak membantu, karena membekukan aplikasi di breakpoint akan membuat masalah hilang.
Taruhan terbaik Anda adalah memasukkan banyak panggilan logging (Log.XXX ()) ke utas dan panggilan balik aplikasi yang berbeda dan lihat di mana penundaannya. Jika Anda membutuhkan stacktrace, buat Exception baru (cukup instantiate) dan catat.
sumber
Apa yang Memicu ANR?
Secara umum, sistem menampilkan PPA jika aplikasi tidak dapat menanggapi input pengguna.
Dalam situasi apa pun di mana aplikasi Anda melakukan operasi yang berpotensi panjang, Anda tidak boleh melakukan pekerjaan pada utas UI, melainkan membuat utas pekerja dan melakukan sebagian besar pekerjaan di sana. Ini membuat utas UI (yang menggerakkan loop peristiwa antarmuka pengguna) berjalan dan mencegah sistem menyimpulkan bahwa kode Anda telah dibekukan.
Cara Menghindari ANR
Aplikasi Android biasanya berjalan seluruhnya pada satu utas secara default "utas UI" atau "utas utama"). Ini berarti apa pun yang dilakukan aplikasi Anda di utas UI yang membutuhkan waktu lama untuk diselesaikan dapat memicu dialog PPA karena aplikasi Anda tidak memberikan kesempatan kepada dirinya sendiri untuk menangani acara masukan atau siaran maksud.
Oleh karena itu, metode apa pun yang berjalan di utas UI harus melakukan pekerjaan sesedikit mungkin pada utas itu. Secara khusus, kegiatan harus dilakukan sesedikit mungkin untuk mengatur dalam metode siklus hidup utama seperti onCreate () dan onResume (). Operasi yang berpotensi berjalan lama seperti operasi jaringan atau basis data, atau perhitungan yang mahal secara komputasi seperti mengubah ukuran bitmap harus dilakukan dalam utas pekerja (atau dalam kasus operasi basis data, melalui permintaan asinkron).
Kode: Utas pekerja dengan kelas AsyncTask
Kode: Jalankan utas Pekerja
Untuk mengeksekusi utas pekerja ini, cukup buat sebuah instance dan panggil execute ():
Sumber
http://developer.android.com/training/articles/perf-anr.html
sumber
masalah saya dengan PPA, setelah banyak pekerjaan saya menemukan bahwa utas memanggil sumber daya yang tidak ada dalam tata letak, alih-alih mengembalikan pengecualian, saya mendapat P ...
sumber
Anda perlu mencari "waiting to lock" di file /data/anr/traces.txt
untuk detail lebih lanjut: Insinyur untuk Kinerja Tinggi dengan Alat dari Android & Play (Google I / O '17)
sumber
Dasar pada @Horyun Lee menjawab, saya menulis skrip python kecil untuk membantu menyelidiki ANR dari
traces.txt
.ANRs akan ditampilkan sebagai grafik
graphviz
jika Anda telah menginstalgrapvhviz
pada sistem Anda.Sebuah png akan menampilkan seperti di bawah ini jika ada PPA terdeteksi dalam file
traces.txt
. Ini lebih intuitif.File sampel yang
traces.txt
digunakan di atas didapat dari sini .sumber
Pertimbangkan untuk menggunakan perpustakaan ANR-Watchdog untuk secara akurat melacak dan menangkap jejak tumpukan ANR dalam detail tingkat tinggi. Anda kemudian dapat mengirimnya ke perpustakaan pelaporan kerusakan Anda. Saya sarankan menggunakan
setReportMainThreadOnly()
dalam skenario ini. Anda dapat membuat aplikasi melemparkan pengecualian non-fatal dari titik beku, atau membuat kekuatan aplikasi berhenti ketika ANR terjadi.Perhatikan bahwa laporan PPA standar yang dikirim ke konsol Pengembang Google Play Anda seringkali tidak cukup akurat untuk menunjukkan masalah yang sebenarnya. Itu sebabnya perpustakaan pihak ketiga diperlukan.
sumber