A simple watchdog that detects Android ANR (Application Not Responding) error and throws a meaningful exception

Overview

Maven Central MIT License GitHub issues Donate

ANR-WatchDog

A simple watchdog that detects Android ANRs (Application Not Responding).

Table of contents

Why it exists

There is currently no way for an android application to catch and report ANR errors.
If your application is not in the play store (either because you are still developing it or because you are distributing it differently), the only way to investigate an ANR is to pull the file /data/anr/traces.txt.
Additionally, we found that using the Play Store was not as effective as being able to choose our own bug tracking service.

There is an issue entry in the android bug tracker describing this lack, feel free to star it ;)

What it does

It sets up a "watchdog" timer that will detect when the UI thread stops responding. When it does, it raises an error with all threads stack traces (main first).

Can it work with crash reporters?

Yes! I'm glad you asked: That's the reason why it was developed in the first place!
As this throws an error, a crash handler can intercept it and handle it the way it needs.

Known working crash reporters include:

And there is no reason why it should not work with [insert your favourite crash reporting system here].

How it works

The watchdog is a simple thread that does the following in a loop:

  1. Schedules a runnable to be run on the UI thread as soon as possible.
  2. Wait for 5 seconds. (5 seconds is the default, but it can be configured).
  3. See if the runnable has been run. If it has, go back to 1.
  4. If the runnable has not been run, which means that the UI thread has been blocked for at least 5 seconds, it raises an error with all running threads stack traces.

Usage

Install

With Gradle / Android Studio

  1. In the app/build.gradle file, add:

    implementation 'com.github.anrwatchdog:anrwatchdog:1.4.0'
    
  2. In your application class, in onCreate, add:

    new ANRWatchDog().start();

With Eclipse

  1. Download the latest jar

  2. Put the jar in the libs/ directory of your project

Reading the ANRError exception report

The ANRError stack trace is a bit particular, it has the stack traces of all the threads running in your application. So, in the report, each caused by section is not the cause of the precedent exception, but the stack trace of a different thread.

Here is a dead lock example:

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)

From this report, we can see that the stack traces of two threads. The first (the "main" thread) is stuck at MainActivity.java:46 while the second thread (named "App: Locker") is locked in a Sleep at MainActivity.java:18.
From there, if we looked at those two lines, we would surely understand the cause of the dead lock!

Note that some crash reporting library (such as Crashlytics) report all thread stack traces at the time of an uncaught exception. In that case, having all threads in the same exception can be cumbersome. In such cases, simply use setReportMainThreadOnly().

Configuration

Timeout (minimum hanging time for an ANR)

To set a different timeout (5000 millis is the default):

if (BuildConfig.DEBUG == false) {
  new ANRWatchDog(10000 /*timeout*/).start();
}

Debugger

By default, the watchdog will ignore ANRs if the debugger is attached or if the app is waiting for the debugger to attach. This is because it detects execution pauses and breakpoints as ANRs. To disable this and throw an ANRError even if the debugger is connected, you can add setIgnoreDebugger(true):

new ANRWatchDog().setIgnoreDebugger(true).start();

On ANR callback

If you would prefer not to crash the application when an ANR is detected, you can enable a callback instead:

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();

This is very important when delivering your app in production. When in the hand of the final user, it's probably better not to crash after 5 seconds, but simply report the ANR to whatever reporting system you use. Maybe, after some more seconds, the app will "de-freeze".

Filtering reports

If you would like to have only your own threads to be reported in the ANRError, and not all threads (including system threads such as the FinalizerDaemon thread), you can set a prefix: only the threads whose name starts with this prefix will be reported.

new ANRWatchDog().setReportThreadNamePrefix("APP:").start();

Then, when you start a thread, don't forget to set its name to something that starts with this prefix (if you want it to be reported):

public class MyAmazingThread extends Thread {
    @Override
    public void run() {
        setName("APP: Amazing!");
        /* ... do amazing things ... */
    }
}

If you want to have only the main thread stack trace and not all the other threads, you can:

new ANRWatchDog().setReportMainThreadOnly().start();

ANR Interceptor

Sometimes, you want to know that the application has froze for a certain duration, but not report the ANR error just yet. You can define an interceptor that will be called before reporting an error. The role of the interceptor is to define whether or not, given the given freeze duration, an ANR error should be raised or postponed.

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;
    }
})

In this example, the ANRWatchDog starts with a timeout of 2000 ms, but the interceptor will postpone the error until at least 5000 ms of freeze has been reached.

Watchdog thread

ANRWatchDog is a thread, so you can interrupt it at any time.

If you are programming with Android's multi process capability (like starting an activity in a new process), remember that you will need an ANRWatchDog thread per process.

Donate

ANR-Watchdog is free to use for both non-profit and commercial use and always will be.

If you wish to show some support or appreciation to my work, you are free to donate!

This would be (of course) greatly appreciated but is by no means necessary to receive help or support, which I'll be happy to provide for free :)

Comments
  • Caught Exceptions having error object from ANRWatchDog not getting logged on Crashlytics Dashboard

    Caught Exceptions having error object from ANRWatchDog not getting logged on Crashlytics Dashboard

    Hi,

    I am using ANRWatchDog to catch ANRs. It provides an 'error' object which I am logging to crashlytics. I am getting report upload complete logs for crashlytics but nothing appears on dashboard. Crashlytics is working fine at the same time for other types of caught/uncaught exceptions.

    private ANRListener listener = new ANRListener() { @Override public void onAppNotResponding(ANRError error) { try{ Crashlytics.logException(error);

            } catch (Exception e) {
                Logger.e(TAG, "Exception while sending ANR stacktrace to Crash reporter "+e.getStackTrace());
            }
    
        }
    };
    

    I have raised the issue with Crashlytics team as well. Wanted to know here if any known issue exists in ANRWatchDog.

    opened by harminderkharbanda 10
  • sometimes it will not cash when I use the watchdog

    sometimes it will not cash when I use the watchdog

    I use the watchdog in my app, why sometime it will crash when anr, but sometimes the android os anr dialog will appear(then it will not crash)? I just code it by the default way: new ANRWatchDog().start();

    opened by HolenZhou 8
  • Suspiciously short list of threads when recording ANRError as Crashlytics non-fatal exception

    Suspiciously short list of threads when recording ANRError as Crashlytics non-fatal exception

    Hi!

    I integrated ANR-WatchDog to a Unity game using custom implementation of UnityPlayerActivity.

    At first I released a game with the default behaviour of the ANR-WatchDog. My app crashed due to unhandled ANRError and Firebase Crashlytics recorded something around 40 threads at this moment including UnityMain thread and others. I used setReportMainThreadOnly() because Crashlytics collects all threads by itself on fatal errors.

    Then I turned this crash to a non-fatal using this code:

        @Override protected void onCreate(Bundle savedInstanceState)
        {
            ANRWatchDog watchDog = new ANRWatchDog();
            watchDog.setANRListener(new ANRWatchDog.ANRListener() {
                @Override
                public void onAppNotResponding(ANRError error) {
                    FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
                    crashlytics.recordException(error);
                }
            });
            watchDog.start();
    
            super.onCreate(savedInstanceState);
        }
    

    This code records ANRError as a non-fatal exception and Crashlytics attaches stack traces contained in ANRError. That is why you do not see setReportMainThreadOnly() here any more. But now crash reports a very short, containing only 8-10 threads. What is strange there were no UnityMain thread while this non-fatal was triggered in the middle of a gameplay.

    Please help, any ideas on how to get full list of stack traces attached?

    opened by AntonPetrov83 7
  • Watchdog send error to Fabric (Crashlytics)

    Watchdog send error to Fabric (Crashlytics)

    Hello, I implemented WathchDog in my project. Boot seem like it has problem with WatchDog version 1.0.3. The logs were not send to Fabric although I catched the error . Please help me check it. Here's the code new ANRWatchDog().setANRListener(new ANRWatchDog.ANRListener() { @Override public void onAppNotResponding(ANRError arg0) { Crashlytics.getInstance().core.logException(arg0); } }).start();

    Thank you.

    opened by giaotuancse 5
  • Exception thrown by ANR WatchDog not catchable by ACRA

    Exception thrown by ANR WatchDog not catchable by ACRA

    Hi,

    I was trying to use ANR WatchDog and ACRA to catch a bug, but when the ANR WatchDog triggers, ACRA doesn't actually catch the exception, but throws an error itself and therefore hands off the exception to the system, which then promptly kills the app. The error seems to be related to ACRA trying to serialize the exception generated by ANR WatchDog (see below).

    I am using ACRA 4.8.2, and ANR WatchDog 1.1.*.

    Any help would be greatly appreciated. Thanks!

    03-07 17:52:43.984 18923-18953/ch.ione.safefingerprint E/ACRA: ACRA caught a ANRError for ch.ione.safefingerprint
                                                                   com.github.anrwatchdog.ANRError: Application Not Responding
                                                                   Caused by: com.github.anrwatchdog.ANRError$$$_Thread: main
                                                                       at android.os.BinderProxy.transactNative(Native Method)
                                                                       at android.os.BinderProxy.transact(Binder.java)
                                                                       at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
                                                                       at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:681)
                                                                       at android.os.BinderProxy.transact(<Xposed>)
                                                                       at com.fingerprint.service.IFingerprintService$Stub$Proxy.open(IFingerprintService.java:259)
                                                                       at com.fingerprint.service.FingerprintManager.<init>(FingerprintManager.java:102)
                                                                       at com.fingerprint.service.FingerprintManager.open(FingerprintManager.java:149)
                                                                       at ch.ione.safefingerprint.fingerprint.FingerprintFPCImpl.getIds(FingerprintFPCImpl.java:91)
                                                                       at ch.ione.safefingerprint.fingerprint.FingerprintDelegate.getIds(FingerprintDelegate.java:53)
                                                                       at ch.ione.safefingerprint.service.FingerprintAuthenticationService.getIds(FingerprintAuthenticationService.java:252)
                                                                       at ch.ione.safefingerprint.ui.fragments.ManageFingerprintsFragment.updateFingerprintList(ManageFingerprintsFragment.java:205)
                                                                       at ch.ione.safefingerprint.ui.fragments.ManageFingerprintsFragment.access$100(ManageFingerprintsFragment.java:29)
                                                                       at ch.ione.safefingerprint.ui.fragments.ManageFingerprintsFragment$6.onServiceConnected(ManageFingerprintsFragment.java:118)
                                                                       at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java)
                                                                       at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java)
                                                                       at android.os.Handler.handleCallback(Handler.java)
                                                                       at android.os.Handler.dispatchMessage(Handler.java)
                                                                       at android.os.Looper.loop(Looper.java)
                                                                       at android.app.ActivityThread.main(ActivityThread.java)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
                                                                       at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:117)
                                                                    Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerDaemon
                                                                       at java.lang.Object.wait(Native Method)
                                                                       at java.lang.Object.wait(Object.java:422)
                                                                       at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:101)
                                                                       at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:72)
                                                                       at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:173)
                                                                       at java.lang.Thread.run(Thread.java:818)
                                                                    Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerWatchdogDaemon
                                                                       at java.lang.Object.wait(Native Method)
                                                                       at java.lang.Daemons$FinalizerWatchdogDaemon.waitForObject(Daemons.java:239)
                                                                       at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:211)
                                                                       at java.lang.Thread.run(Thread.java:818) 
                                                                    Caused by: com.github.anrwatchdog.ANRError$$$_Thread: GCDaemon
                                                                       at java.lang.Object.wait(Native Method)
                                                                       at java.lang.Daemons$GCDaemon.run(Daemons.java:341)
                                                                       at java.lang.Thread.run(Thread.java:818) 
                                                                    Caused by: com.github.anrwatchdog.ANRError$$$_Thread: HeapTrimmerDaemon
                                                                       at java.lang.Object.wait(Native Method)
                                                                       at java.lang.Daemons$HeapTrimmerDaemon.run(Daemons.java:310)
                                                                       at java.lang.Thread.run(Thread.java:818) 
                                                                    Caused by: com.github.anrwatchdog.ANRError$$$_Thread: ReferenceQueueDaemon
                                                                       at java.lang.Object.wait(Native Method)
                                                                       at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:133)
                                                                       at java.lang.Thread.run(Thread.java:818) 
                                                                    Caused by: com.github.anrwatchdog.ANRError$$$_Thread: |ANR-WatchDog|
                                                                       at dalvik.system.VMStack.getThreadStackTrace(Native Method)
                                                                       at java.lang.Thread.getStackTrace(Thread.java:580)
                                                                       at java.lang.Thread.getAllStackTraces(Thread.java:522)
                                                                       at com.github.anrwatchdog.ANRError.New(ANRError.java:80)
                                                                       at com.github.anrwatchdog.ANRWatchDog.run(ANRWatchDog.java:175)
    03-07 17:52:44.094 18923-18953/ch.ione.safefingerprint E/ACRA: ACRA failed to capture the error - handing off to native error reporter
                                                                   java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.github.anrwatchdog.ANRError)
                                                                       at android.os.Parcel.writeSerializable(Parcel.java)
                                                                       at android.os.Parcel.writeValue(Parcel.java)
                                                                       at android.os.Parcel.writeArrayMapInternal(Parcel.java)
                                                                       at android.os.BaseBundle.writeToParcelInner(BaseBundle.java)
                                                                       at android.os.Bundle.writeToParcel(Bundle.java)
                                                                       at android.os.Parcel.writeBundle(Parcel.java)
                                                                       at android.content.Intent.writeToParcel(Intent.java)
                                                                       at android.os.Parcel.writeTypedArray(Parcel.java)
                                                                       at android.app.ActivityManagerProxy.getIntentSender(ActivityManagerNative.java)
                                                                       at android.app.PendingIntent.getActivity(PendingIntent.java)
                                                                       at android.app.PendingIntent.getActivity(PendingIntent.java)
                                                                       at org.acra.builder.ReportExecutor.createNotification(ReportExecutor.java:335)
                                                                       at org.acra.builder.ReportExecutor.execute(ReportExecutor.java:196)
                                                                       at org.acra.builder.ReportBuilder.build(ReportBuilder.java:144)
                                                                       at org.acra.ErrorReporter.uncaughtException(ErrorReporter.java:259)
                                                                       at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
                                                                       at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
                                                                    Caused by: java.io.NotSerializableException: com.github.anrwatchdog.ANRError$$
                                                                       at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344)
                                                                       at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
                                                                       at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
                                                                       at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
                                                                       at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)
                                                                       at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
                                                                       at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
                                                                       at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
                                                                       at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
                                                                       at java.lang.Throwable.writeObject(Throwable.java:436)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                                       at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1033)
                                                                       at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
                                                                       at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
                                                                       at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
                                                                       at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
                                                                       at java.lang.Throwable.writeObject(Throwable.java:436)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                                       at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1033)
                                                                       at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
                                                                       at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
                                                                       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
                                                                       at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
                                                                       at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
                                                                       at java.lang.Throwable.writeObject(Throwable.java:436)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                                       at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1033)
                                                                       at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
                                                                    at java.io.ObjectOutputStream.writeObjectInternal(
    03-07 17:52:44.094 18923-18953/ch.ione.safefingerprint I/ACRA: ACRA is disabled for ch.ione.safefingerprint - forwarding uncaught Exception on to default ExceptionHandler
    03-07 17:52:44.095 18923-18953/ch.ione.safefingerprint E/AndroidRuntime: FATAL EXCEPTION: |ANR-WatchDog|
                                                                             Process: ch.ione.safefingerprint, PID: 18923
                                                                             com.github.anrwatchdog.ANRError: Application Not Responding
                                                                             Caused by: com.github.anrwatchdog.ANRError$$$_Thread: main
                                                                                 at android.os.BinderProxy.transactNative(Native Method)
                                                                                 at android.os.BinderProxy.transact(Binder.java)
                                                                                 at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
                                                                                 at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:681)
                                                                                 at android.os.BinderProxy.transact(<Xposed>)
                                                                                 at com.fingerprint.service.IFingerprintService$Stub$Proxy.open(IFingerprintService.java:259)
                                                                                 at com.fingerprint.service.FingerprintManager.<init>(FingerprintManager.java:102)
                                                                                 at com.fingerprint.service.FingerprintManager.open(FingerprintManager.java:149)
                                                                                 at ch.ione.safefingerprint.fingerprint.FingerprintFPCImpl.getIds(FingerprintFPCImpl.java:91)
                                                                                 at ch.ione.safefingerprint.fingerprint.FingerprintDelegate.getIds(FingerprintDelegate.java:53)
                                                                                 at ch.ione.safefingerprint.service.FingerprintAuthenticationService.getIds(FingerprintAuthenticationService.java:252)
                                                                                 at ch.ione.safefingerprint.ui.fragments.ManageFingerprintsFragment.updateFingerprintList(ManageFingerprintsFragment.java:205)
                                                                                 at ch.ione.safefingerprint.ui.fragments.ManageFingerprintsFragment.access$100(ManageFingerprintsFragment.java:29)
                                                                                 at ch.ione.safefingerprint.ui.fragments.ManageFingerprintsFragment$6.onServiceConnected(ManageFingerprintsFragment.java:118)
                                                                                 at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java)
                                                                                 at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java)
                                                                                 at android.os.Handler.handleCallback(Handler.java)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java)
                                                                                 at android.os.Looper.loop(Looper.java)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
                                                                                 at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:117)
                                                                              Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerDaemon
                                                                                 at java.lang.Object.wait(Native Method)
                                                                                 at java.lang.Object.wait(Object.java:422)
                                                                                 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:101)
                                                                                 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:72)
                                                                                 at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:173)
                                                                                 at java.lang.Thread.run(Thread.java:818)
                                                                              Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerWatchdogDaemon
                                                                                 at java.lang.Object.wait(Native Method)
                                                                                 at java.lang.Daemons$FinalizerWatchdogDaemon.waitForObject(Daemons.java:239)
                                                                                 at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:211)
                                                                                 at java.lang.Thread.run(Thread.java:818) 
                                                                              Caused by: com.github.anrwatchdog.ANRError$$$_Thread: GCDaemon
                                                                                 at java.lang.Object.wait(Native Method)
                                                                                 at java.lang.Daemons$GCDaemon.run(Daemons.java:341)
                                                                                 at java.lang.Thread.run(Thread.java:818) 
                                                                              Caused by: com.github.anrwatchdog.ANRError$$$_Thread: HeapTrimmerDaemon
                                                                                 at java.lang.Object.wait(Native Method)
                                                                                 at java.lang.Daemons$HeapTrimmerDaemon.run(Daemons.java:310)
                                                                                 at java.lang.Thread.run(Thread.java:818) 
                                                                              Caused by: com.github.anrwatchdog.ANRError$$$_Thread: ReferenceQueueDaemon
                                                                                 at java.lang.Object.wait(Native Method)
                                                                                 at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:133)
                                                                                 at java.lang.Thread.run(Thread.java:818) 
                                                                              Caused by: com.github.anrwatchdog.ANRError$$$_Thread: |ANR-WatchDog|
                                                                                 at dalvik.system.VMStack.getThreadStackTrace(Native Method)
                                                                                 at java.lang.Thread.getStackTrace(Thread.java:580)
                                                                                 at java.lang.Thread.getAllStackTraces(Thread.java:522)
                                                                                 at com.github.anrwatchdog.ANRError.New(ANRError.java:80)
                                                                                 at com.github.anrwatchdog.ANRWatchDog.run(ANRWatchDog.java:175)
    
    opened by rssc 5
  • It's possible to make it work in debug mode too

    It's possible to make it work in debug mode too

    Re note:

    Note that this will not enable the watchdog in debug mode, because the watchdog will prevent the debugger from hanging execution at breakpoints or exceptions (it will detect the debugging pause as an ANR).

    You could easily work around this by checking android.os.Debug#isDebuggerConnected whenever you detect an ANR and just ignore it.

    Can you think of any reason not to do this by default?

    opened by TWiStErRob 5
  • I am getting anr exception, don't know what is root cause

    I am getting anr exception, don't know what is root cause

    01-25 15:37:59.706 17949-17956/in.codersbyte.namostu I/art: Thread[3,tid=17956,WaitingInMainSignalCatcherLoop,Thread*=0x7fa064f400,peer=0x12c24a60,"Signal Catcher"]: reacting to signal 3
    01-25 15:37:59.901 17949-17956/in.codersbyte.namostu I/art: Wrote stack traces to '/data/anr/traces.txt'
    01-25 15:37:59.949 17949-18055/in.codersbyte.namostu E/AndroidRuntime: FATAL EXCEPTION: |ANR-WatchDog|
                                                                           Process: in.codersbyte.namostu, PID: 17949
                                                                           com.github.anrwatchdog.ANRError: Application Not Responding
                                                                           Caused by: com.github.anrwatchdog.ANRError$$$_Thread: main (state = RUNNABLE)
                                                                               at android.view.ThreadedRenderer.nSetStopped(Native Method)
                                                                               at android.view.ThreadedRenderer.setStopped(ThreadedRenderer.java:494)
                                                                               at android.view.ViewRootImpl.draw(ViewRootImpl.java:2831)
                                                                               at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2646)
                                                                               at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2253)
                                                                               at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1288)
                                                                               at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6359)
                                                                               at android.view.Choreographer$CallbackRecord.run(Choreographer.java:873)
                                                                               at android.view.Choreographer.doCallbacks(Choreographer.java:685)
                                                                               at android.view.Choreographer.doFrame(Choreographer.java:621)
                                                                               at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:859)
                                                                               at android.os.Handler.handleCallback(Handler.java:754)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                               at android.os.Looper.loop(Looper.java:163)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:6237)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: Answers Events Handler1 (state = TIMED_WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2077)
                                                                               at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1103)
                                                                               at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1084)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at io.fabric.sdk.android.services.common.ExecutorUtils$1$1.onRun(ExecutorUtils.java:75)
                                                                               at io.fabric.sdk.android.services.common.BackgroundPriorityRunnable.run(BackgroundPriorityRunnable.java:30)
                                                                               at java.lang.Thread.run(Thread.java:760)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: AsyncTask #10 (state = TIMED_WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2077)
                                                                               at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:438)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1057)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: AsyncTask #9 (state = TIMED_WAITING)
                                                                               at java.lang.Object.wait(Native Method) 
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160) 
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325) 
                                                                               at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201) 
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2077) 
                                                                               at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:438) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1057) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118) 
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: Crashlytics Exception Handler1 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
    01-25 15:37:59.950 17949-18055/in.codersbyte.namostu E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at io.fabric.sdk.android.services.common.ExecutorUtils$1$1.onRun(ExecutorUtils.java:75)
                                                                               at io.fabric.sdk.android.services.common.BackgroundPriorityRunnable.run(BackgroundPriorityRunnable.java:30)
                                                                               	... 1 more
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FileObserver (state = RUNNABLE)
                                                                               at android.os.FileObserver$ObserverThread.observe(Native Method)
                                                                               at android.os.FileObserver$ObserverThread.run(FileObserver.java:85)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerDaemon (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Object.wait(Object.java:407)
                                                                               at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:188)
                                                                               at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:209)
                                                                               at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:204)
                                                                               at java.lang.Thread.run(Thread.java:760)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerWatchdogDaemon (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded(Daemons.java:269)
                                                                               at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:249)
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FrescoDecodeExecutor-1 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(PriorityThreadFactory.java:53)
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FrescoIoBoundExecutor-1 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method) 
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160) 
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325) 
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161) 
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035) 
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118) 
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                                               at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(PriorityThreadFactory.java:53) 
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FrescoLightWeightBackgroundExecutor-1 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method) 
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160) 
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325) 
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161) 
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035) 
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118) 
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                                               at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(PriorityThreadFactory.java:53) 
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: HeapTaskDaemon (state = BLOCKED)
                                                                               at dalvik.system.VMRuntime.runHeapTasks(Native Method)
                                                                               at java.lang.Daemons$HeapTaskDaemon.run(Daemons.java:433)
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: OkHttp ConnectionPool (state = TIMED_WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at com.android.okhttp.ConnectionPool.performCleanup(ConnectionPool.java:307)
                                                                               at com.android.okhttp.ConnectionPool.runCleanupUntilPoolIsEmpty(ConnectionPool.java:244)
                                                                               at com.android.okhttp.ConnectionPool.-wrap0(ConnectionPool.java)
                                                                               at com.android.okhttp.ConnectionPool$1.run(ConnectionPool.java:98)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: Okio Watchdog (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at com.android.okhttp.okio.AsyncTimeout.awaitTimeout(AsyncTimeout.java:311)
                                                                               at com.android.okhttp.okio.AsyncTimeout.-wrap0(AsyncTimeout.java)
                                                                               at com.android.okhttp.okio.AsyncTimeout$Watchdog.run(AsyncTimeout.java:286)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: Queue (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
    01-25 15:37:59.951 17949-18055/in.codersbyte.namostu E/AndroidRuntime:     at java.util.concurrent.PriorityBlockingQueue.take(PriorityBlockingQueue.java:519)
                                                                               at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.performOperation(DependencyPriorityBlockingQueue.java:197)
                                                                               at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.get(DependencyPriorityBlockingQueue.java:236)
                                                                               at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.take(DependencyPriorityBlockingQueue.java:65)
                                                                               at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.take(DependencyPriorityBlockingQueue.java:46)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at java.lang.Thread.run(Thread.java:760)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: ReferenceQueueDaemon (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:150)
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: Thread-18 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: Thread-19 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method) 
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160) 
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325) 
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161) 
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035) 
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118) 
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: Thread-7 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method) 
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160) 
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325) 
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161) 
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035) 
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118) 
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: fifo-pool-thread-0 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
                                                                               at java.util.concurrent.PriorityBlockingQueue.take(PriorityBlockingQueue.java:519)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at java.lang.Thread.run(Thread.java:760)
                                                                               at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: pool-1-thread-1 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method)
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160)
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325)
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                               at java.lang.Thread.run(Thread.java:760)
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: pool-7-thread-1 (state = WAITING)
                                                                               at java.lang.Object.wait(Native Method) 
                                                                               at java.lang.Thread.parkFor$(Thread.java:2160) 
                                                                               at sun.misc.Unsafe.park(Unsafe.java:325) 
                                                                               at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161) 
                                                                               at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035) 
                                                                               at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058) 
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118) 
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                                               at java.lang.Thread.run(Thread.java:760) 
                                                                            Caused by: com.github.anrwatchdog.ANRError$$$_Thread: |ANR-WatchDog| (state = RUNNABLE)
                                                                               at dalvik.system.VMStack.getThreadStackTrace(Native Method)
    01-25 15:37:59.952 17949-18055/in.codersbyte.namostu E/AndroidRuntime:     at java.lang.Thread.getStackTrace(Thread.java:1565)
                                                                               at java.lang.Thread.getAllStackTraces(Thread.java:1615)
                                                                               at com.github.anrwatchdog.ANRError.New(ANRError.java:72)
                                                                               at com.github.anrwatchdog.ANRWatchDog.run(ANRWatchDog.java:209)
    
    opened by amankumarjain 3
  • ANR-WatchDog not works with Fabric(Crashlytics)

    ANR-WatchDog not works with Fabric(Crashlytics)

    Hello, I've implemented WatchDog in my project. But it has some problem with Fabric. I catched the error then sent ANR error to Fabric but it seem not work

            new ANRWatchDog().setANRListener(new ANRWatchDog.ANRListener() {
    
                @Override
                public void onAppNotResponding(ANRError arg0) {
                       Crashlytics.getInstance().core.logException(arg0);
                }
            }).start();
    
    opened by giaotuancse 3
  • How to be sure if main thread is blocked or not?

    How to be sure if main thread is blocked or not?

    Hi, I've found your project with how to detect ANR in Android and I found it very useful, thanks a lot. But there is a port that I don't quite understand that how do you be sure if main thread is blocked? Your code:

    public void run() {
        setName("|ANR-WatchDog|");
    
        int lastTick;
        while (!isInterrupted()) {
            lastTick = _tick;
            _uiHandler.post(_ticker);
            try {
                Thread.sleep(_timeoutInterval);
            }
            catch (InterruptedException e) {
                _interruptionListener.onInterrupted(e);
                return ;
            }
    
            // If the main thread has not handled _ticker, it is blocked. ANR.
            if (_tick == lastTick) {
                ANRError error;
                if (_namePrefix != null)
                    error = ANRError.New(_namePrefix, _logThreadsWithoutStackTrace);
                else
                    error = ANRError.NewMainOnly();
                _anrListener.onAppNotResponding(error);
                return ;
            }
        }
    }
    

    The value of current _tick is passed to lastTick before Runnable _ticker is passed to main thread. Let's assume _tick is 0 which means lastTick is 0 as well. Then the watchDog thread is gonna sleep for 5s without interruption. Then the code check if the new _tick equals lastTick:

    if (_tick == lastTick)
    

    By that I saw that if the new value of _tick equals the value of lastTick then we know the thread is blocked. This is the part I just don't understand, isn't it possible that the new value of _tick is 0 since its value will be set between 0~9 (_tick = (_tick + 1) % 10)??? Is there anything wrong about my analysis about this? I knew that it has to be something wrong with myself but I just can't find out, hope somebody can help me, thanks a lot!

    opened by PanWangJ 3
  • Changes for upstream

    Changes for upstream

    Hi Salomon!

    These are our changes. We were liberal with renaming, so let me know if you would like me to revert our renames to preserve your public API. Thank you for a great library!

    opened by ndahlquist 3
  • Thread timeout?

    Thread timeout?

    Hey, this is a fantastic project and very useful indeed. I am using the below code for checking ANRs :

    ` // ANR Reporting

        /*if (BuildConfig.DEBUG == false) {
            new ANRWatchDog(5000 *//*timeout*//*).start();
        }*/
    
        new ANRWatchDog().setIgnoreDebugger(true).start();
    
        // Prevent app termination
        new ANRWatchDog().setANRListener(new ANRWatchDog.ANRListener() {
            @Override
            public void onAppNotResponding(ANRError error) {
                // Handle the error. For example, log it to HockeyApp:
                Intent cu = new Intent(UriActivity.this, CrashActivity.class);
                if(error!=null) {
                    cu.putExtra("errorx", error.toString());
                }
                startActivity(cu);
            }
        }).start();
    
        // ANR Reporting End`
    

    My questions are

    1. Do I need to insert above code for every activity to check ANRs or launcher activity itself is enough? Meaning, does it have context only for the current activity or has context of all activities in the app. Lets say I launch another activity other than the launcher activity using a service, then will I get ANR on that particular non launcher activity? There can be a limit to number of parallel threads allowed on a particular android device that is why I wanted raise this question. Say I use above code in 5 activities, I will have 4 unnecessary parallel threads.

    2. Can I use it on any of my apps with commercial use? Is the license Open Source?

    Thanks!

    opened by wisejoy7 2
  • Insert ticker runnable using Handler.postAtFrontOfQueue

    Insert ticker runnable using Handler.postAtFrontOfQueue

    Insert ticker runnable using Handler.postAtFrontOfQueue instead of Handler.post method, which adds a message to the end of the queue. This way we detect timeout of the currently running runnable and not the timeout of the queue of runnables that happens to be in front of the ticker runnable.

    opened by zmiceruk 0
  • Set Thread priority below main thread.

    Set Thread priority below main thread.

    Currently, both the ANR watchdog thread and main thread has the same nice value. Add the following line at the start of the run() function to resolve the issue.

    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)

    Screenshot 2022-03-07 at 2 30 01 PM
    opened by anjalsaneen 0
  • Race condition for _tick and _reported

    Race condition for _tick and _reported

    1. Let assume that we use all the default callbacks and values.
    2. When the _ticker is not called during 5sec and we recognise this as ANR and send the report, assign interval initial value and set the _reported to true.
    3. We start our while cycle from the beginning: _tick is not 0 so we don't schedule _ticker again - it is ok, next we put our thread to the sleep on 5sec one more time.
    4. But imagine that our _ticker is not called again during this 5s but is called at the time when we step on condition "if (_tick != 0 && !_reported)" and it is race condition because we write and read _tick and _reported at the same moment of time.

    Best, Taras

    opened by tovchenko 0
  • Support for getStackTrace() and setStackTrace()

    Support for getStackTrace() and setStackTrace()

    Hi Salomon,

    We're in the process of integrating your plugin in our app.

    It would be very beneficial to be able to manipulate the stack trace before sending the ANRError to Firebase Crashlytics, so we can group the ANR issues together in the console there. Crashlytics groups the issues based on the topmost frame in the stack trace, so we were thinking of adding a custom frame to the top to let Firebase know that it belongs next to other ANR issues.

    I've tried using couple of methods inherited from Throwable, but they don't seem to be overriden in the ANRError class - getStackTrace() returns an empty array and setStackTrace() doesn't seem to do anything.

    So my questions are:

    1. Is there a way to add a custom frame to the top of the stack trace in the ANRError?
    2. If not, do you plan to add the support for manipulating the stack trace of the ANRError?

    BTW, thanks for creating this plugin and making it open-source! It's a lifesaver amidst the current shortage of ANR detectors 😃

    opened by kodoman 1
  • It seems not so good to start the anr-watchdog on application oncreate

    It seems not so good to start the anr-watchdog on application oncreate

    If using new ANRWatchDog().start() on application oncreate function. then it will begin to post a delay message(defalut 5000ms), while on application oncreate function, there may be init some tasks in UI Thread may need more than 5000 ms with some low mobile devices, thus it will cause the not real anr with anr-watchDog.

    opened by zhuozp 0
Releases(v1.0)
Owner
Salomon BRYS
Salomon BRYS
An app performance monitor(APM) , like "Android Studio profiler", you can easily monitor the performance of your app real time in browser

AndroidGodEye English README.md 中文 README_zh.md Android developer lack of monitoring of performance data,especially in production environment. so we n

AndroidKy 2.5k Dec 29, 2022
Android TextView with rich support of compound drawables

TextViewRichDrawable This is a tiny library which empowers TextView's (and its inheritors) compound drawables with size specifying, vector support and

Oleksandr Tolstykh 135 Nov 29, 2022
An Android app that scans images or human faces in real time and detects whether the mask is worn or not, with the ability to set an audible alert

Swift Mask Real time face mask detection Brief overview Swift Mask scans images or human faces in real time and detects whether the mask is worn or no

Giorgio Cantoni 4 Sep 22, 2022
A simple IntelliJ project to demonstrate exception handling in coroutines

ExceptionHandling A simple IntelliJ project to demonstrate exception handling in coroutines NB:** launch coroutine builder type exceptions cannot be h

Felix Nzioki Savali 0 Nov 9, 2021
Easy android exception tracer and handler.

Introduction Lup is a small android library that can help you to tracking bug that causes application stopped working (force close). Whiting this libr

icodeu 4 Sep 29, 2022
An application demoing meaningful motion on Android

Animate You'll find the supporting medium article for this project here! Animate is a simple application I quickly put together to demo meaningful mot

Joe Birch 3.1k Dec 30, 2022
How to apply meaningful and delightful motion in a sample Android app

Applying meaningful motion on Android How to apply meaningful and delightful motion in a sample Android app Read the complete post at https://medium.c

André Mion 166 Nov 12, 2022
How to apply meaningful and delightful motion in a sample Android app

Applying meaningful motion on Android How to apply meaningful and delightful motion in a sample Android app Read the complete post at https://medium.c

André Mion 167 Dec 19, 2022
How to apply meaningful and delightful motion in a sample Android app

Applying meaningful motion on Android How to apply meaningful and delightful motion in a sample Android app Read the complete post at https://medium.c

André Mion 167 Dec 19, 2022
RxJava 2.x extension to provide meaningful Stack Traces

RxJava2Debug A library to make StackTraces involving RxJava2 more meaningful (they will always point to your code!). Rationale If you use RxJava2, you

Mikel 668 Dec 15, 2022
[Development stopped in 2014. Unfinished and not stable - not recommended to use.] An easy-to-use ViewPager subclass with parallax background effect for Android apps.

Development stopped in 2014 Not developed since 2014. Unfinished and not stable - not recommended to use. ParallaxViewPager An easy-to-use ViewPager s

Andras Kindler 437 Dec 29, 2022
Button for android with animations for transition and error states.

Transition Button Android Preview Expand animation: Shake animation: Installation Gradle dependencies { implementation 'com.royrodriguez:transitionbu

Roy Rodriguez 137 Jan 3, 2023
Error handling library for Android and Java

ErrorHandler Error handling library for Android and Java Encapsulate error handling logic into objects that adhere to configurable defaults. Then pass

null 237 Dec 29, 2022
Robust error-handling for Kotlin and Android

Code Complete: A Practical Handbook of Software Construction, on error-handling techniques: Consumer applications tend to favor robustness to correctn

Specto Inc. 36 Dec 13, 2022
🪟 Pluggable Ktor plugin to implement Sentry for error handling and request contexts

?? Ktor Plugin for Sentry Pluggable Ktor plugin to implement Sentry for error handling and request contexts. What is this library? This basically impl

Noel 3 Dec 6, 2022
See a pretty error screen when your Android app crashes

WhatTheStack WhatTheStack is a library to make your debugging experience on Android better. It shows you a pretty error screen when your Android App c

Kshitij Chauhan 241 Nov 11, 2022
Powerful Error Detector for Android

Erratum Powerful Error Detector for Android Preview If an exception is detected, the exception activity is automatically launched. This activity also

Ji Sungbin 5 Dec 3, 2022
A lightweight, good expandability Android library used for displaying different pages like loading, error, empty, timeout or even your custom page when you load a page

中文 | English LoadSir ?? ?? LoadSir是一个高效易用,低碳环保,扩展性良好的加载反馈页管理框架,在加载网络或其他数据时候,根据需求切换状态页面, 可添加自定义状态页面,如加载中,加载失败,无数据,网络超时,如占位图,登录失效等常用页面。可配合网络加载框架,结合返回 状态

KingJA 3.3k Dec 21, 2022
Create & Show progress, data or error views, the easy way!

State Views for Android (BETA version) Create & Show progress, data or error views, the easy way! StateViews is based on ViewSwitcher mechanism and al

Mehdi Sakout 376 Dec 21, 2022
Collects error messages ad sends them to Microsoft Teams or Telegram

ErrorCollector Logback-classic This projects aims to provide a convenient way to be notified if an error in on of your systems occurs. The appender wi

Mayope 4 Jan 11, 2022