Pengawas sederhana yang mendeteksi ANR Android (Aplikasi Tidak Merespons).
Saat ini tidak ada cara bagi aplikasi android untuk menangkap dan melaporkan kesalahan ANR.
Jika aplikasi Anda tidak ada di play store (karena Anda masih mengembangkannya atau karena Anda mendistribusikannya secara berbeda), satu-satunya cara untuk menyelidiki ANR adalah dengan menarik file /data/anr/traces.txt.
Selain itu, kami menemukan bahwa menggunakan Play Store tidak seefektif memilih layanan pelacakan bug kami sendiri.
Ada entri masalah di pelacak bug android yang menjelaskan kekurangan ini, jangan ragu untuk memberi bintang pada itu ;)
Ini menyiapkan pengatur waktu "pengawas" yang akan mendeteksi kapan thread UI berhenti merespons. Jika ya, ini akan memunculkan kesalahan dengan semua jejak tumpukan thread (yang utama terlebih dahulu).
Ya! Saya senang Anda bertanya: Itulah alasan mengapa ini dikembangkan!
Saat ini menimbulkan kesalahan, pengendali kerusakan dapat mencegatnya dan menanganinya sesuai kebutuhan.
Pelapor kecelakaan kerja yang terkenal meliputi:
setReportMainThreadOnly()
)Dan tidak ada alasan mengapa ini tidak berfungsi dengan [masukkan sistem pelaporan kerusakan favorit Anda di sini] .
Watchdog adalah thread sederhana yang melakukan hal berikut dalam satu lingkaran:
Di file app/build.gradle
, tambahkan:
implementation 'com.github.anrwatchdog:anrwatchdog:1.4.0'
Di kelas aplikasi Anda, di onCreate
, tambahkan:
new ANRWatchDog (). start ();
Unduh toples terbaru
Letakkan toples di direktori libs/
proyek Anda
Pelacakan tumpukan ANRError
agak khusus, ia memiliki jejak tumpukan semua thread yang berjalan di aplikasi Anda. Jadi, dalam laporan tersebut, setiap bagian caused by
bukan penyebab pengecualian preseden , tetapi jejak tumpukan dari thread yang berbeda.
Berikut adalah contoh kunci mati:
FATAL EXCEPTION: |ANR-WatchDog|
Process: anrwatchdog.github.com.testapp, PID: 26737
com.github.anrwatchdog.ANRError: Application Not Responding
Caused by: com.github.anrwatchdog.ANRError$_$_Thread: main (state = WAITING)
at testapp.MainActivity$1.run(MainActivity.java:46)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
Caused by: com.github.anrwatchdog.ANRError$_$_Thread: APP: Locker (state = TIMED_WAITING)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:1031)
at java.lang.Thread.sleep(Thread.java:985)
at testapp.MainActivity.SleepAMinute(MainActivity.java:18)
at testapp.MainActivity.access$100(MainActivity.java:12)
at testapp.MainActivity$LockerThread.run(MainActivity.java:36)
Dari laporan ini, kita dapat melihat bahwa tumpukan tersebut menelusuri dua thread. Yang pertama (utas "utama") terhenti di MainActivity.java:46
sedangkan utas kedua (bernama "Aplikasi: Locker") terkunci dalam mode Tidur di MainActivity.java:18
.
Dari situ kalau kita lihat kedua garis tersebut pasti kita akan paham penyebab terjadinya dead lock tersebut!
Perhatikan bahwa beberapa pustaka pelaporan kerusakan (seperti Crashlytics) melaporkan semua jejak tumpukan thread pada saat pengecualian tidak tertangkap. Dalam hal ini, memiliki semua thread dalam pengecualian yang sama bisa jadi rumit. Dalam kasus seperti itu, cukup gunakan setReportMainThreadOnly()
.
Untuk menyetel batas waktu yang berbeda (5000 mili adalah default):
if ( BuildConfig . DEBUG == false ) {
new ANRWatchDog ( 10000 /*timeout*/ ). start ();
}
Secara default, pengawas akan mengabaikan ANR jika debugger terpasang atau jika aplikasi menunggu debugger dipasang. Hal ini karena ia mendeteksi jeda eksekusi dan titik henti sementara sebagai ANR. Untuk menonaktifkan ini dan menampilkan ANRError
meskipun debugger terhubung, Anda dapat menambahkan setIgnoreDebugger(true)
:
new ANRWatchDog (). setIgnoreDebugger ( true ). start ();
Jika Anda memilih untuk tidak membuat aplikasi mogok saat ANR terdeteksi, Anda dapat mengaktifkan callback:
new ANRWatchDog (). setANRListener ( new ANRWatchDog . ANRListener () {
@ Override
public void onAppNotResponding ( ANRError error ) {
// Handle the error. For example, log it to HockeyApp:
ExceptionHandler . saveException ( error , new CrashManager ());
}
}). start ();
Ini sangat penting saat mengirimkan aplikasi Anda dalam produksi. Saat berada di tangan pengguna akhir, mungkin lebih baik tidak terjadi error setelah 5 detik, namun cukup laporkan ANR ke sistem pelaporan apa pun yang Anda gunakan. Mungkin, setelah beberapa detik lagi, aplikasi akan "dibekukan".
Jika Anda hanya ingin thread Anda sendiri dilaporkan di ANRError, dan tidak semua thread (termasuk thread sistem seperti thread FinalizerDaemon
), Anda dapat menyetel awalan: hanya thread yang namanya dimulai dengan awalan ini yang akan dilaporkan .
new ANRWatchDog (). setReportThreadNamePrefix ( "APP:" ). start ();
Kemudian, ketika Anda memulai sebuah thread, jangan lupa untuk menetapkan namanya menjadi sesuatu yang dimulai dengan awalan ini (jika Anda ingin melaporkannya):
public class MyAmazingThread extends Thread {
@ Override
public void run () {
setName ( "APP: Amazing!" );
/* ... do amazing things ... */
}
}
Jika Anda hanya ingin memiliki jejak tumpukan thread utama dan tidak semua thread lainnya, Anda dapat:
new ANRWatchDog (). setReportMainThreadOnly (). start ();
Terkadang, Anda ingin mengetahui bahwa aplikasi terhenti selama jangka waktu tertentu, namun belum melaporkan kesalahan ANR. Anda dapat menentukan pencegat yang akan dipanggil sebelum melaporkan kesalahan. Peran interseptor adalah untuk menentukan apakah kesalahan ANR harus ditingkatkan atau ditunda, mengingat durasi pembekuan yang diberikan.
new ANRWatchDog ( 2000 ). setANRInterceptor ( new ANRWatchDog . ANRInterceptor () {
@ Override
public long intercept ( long duration ) {
long ret = 5000 - duration ;
if ( ret > 0 ) {
Log . w ( TAG , "Intercepted ANR that is too short (" + duration + " ms), postponing for " + ret + " ms." );
}
return ret ;
}
})
Dalam contoh ini, ANRWatchDog memulai dengan batas waktu 2000 mdtk, namun pencegat akan menunda kesalahan hingga setidaknya 5000 mdtk berhenti tercapai.
ANRWatchDog adalah thread, jadi Anda dapat menghentikannya kapan saja.
Jika Anda memprogram dengan kemampuan multiproses Android (seperti memulai aktivitas dalam proses baru), ingatlah bahwa Anda memerlukan thread ANRWatchDog per proses.
ANR-Watchdog dapat digunakan secara gratis baik untuk tujuan nirlaba maupun komersial, dan akan selalu demikian.
Jika Anda ingin menunjukkan dukungan atau penghargaan terhadap karya saya, Anda bebas berdonasi !
Ini (tentu saja) akan sangat dihargai tetapi sama sekali tidak diperlukan untuk menerima bantuan atau dukungan, yang dengan senang hati saya berikan secara gratis :)