Is there a way to get notified when your app triggers an ANR (Application Not Responding)? Similar to the default exception handler?
In anticipation of the "what would you do with it" answers, just logging. Not "doing" anything.
Is there a way to get notified when your app triggers an ANR (Application Not Responding)? Similar to the default exception handler?
In anticipation of the "what would you do with it" answers, just logging. Not "doing" anything.
Since the system watchdog does not warn the application, the application itself can have it's own watchdog. The steps are simple, just start a thread that loops doing the following :
I have written a small library that does exactly that and that I use with ACRA.
I hope it helps ;)
I've been thinking about this quite a bit. You could do the following, although its pretty heavy handed. ANR's write out a threads file to a generally readable directory:
/data/anr/traces.txt
You could have a service, in a different process, poll that file periodically. If the date changes, and your app is at the top, then you probably had an ANR event.
I'm not 100% sure of the format of the file, though.
No. Unlike exceptions that occur within your process's VM that you can catch, the ANR is generated by a system watchdog, outside your VM. Google offers info on triggers and avoidance
This small ANR-WatchDog thread can help you to monitor your app's thread and get notified when ANR happens.
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();
you could use a service (preferably a foreground service) that listens to the logs (using a thread) , and if there is a log that indicate the ANR , handle it.
here's a small sample of an app that causes ANR:
...
findViewById(R.id.button).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(final View v)
{
try
{
Thread.sleep(10000);
}
catch(final InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
...
here's the log that i got from the logcat when i got the ANR:
08-03 13:02:37.746: E/ActivityManager(158): ANR in com.example.anr (com.example.anr/.MainActivity)
08-03 13:02:37.746: E/ActivityManager(158): Reason: keyDispatchingTimedOut
08-03 13:02:37.746: E/ActivityManager(158): Load: 6.19 / 2.37 / 0.86
08-03 13:02:37.746: E/ActivityManager(158): CPU usage from 5598ms to 0ms ago:
08-03 13:02:37.746: E/ActivityManager(158): 2.6% 158/system_server: 2.5% user + 0.1% kernel / faults: 86 minor
08-03 13:02:37.746: E/ActivityManager(158): 0.5% 298/com.android.phone: 0.3% user + 0.1% kernel / faults: 15 minor
08-03 13:02:37.746: E/ActivityManager(158): 0% 35/rild: 0% user + 0% kernel
08-03 13:02:37.746: E/ActivityManager(158): 4.6% TOTAL: 3.9% user + 0.6% kernel
08-03 13:02:37.746: E/ActivityManager(158): CPU usage from 2029ms to 2654ms later:
08-03 13:02:37.746: E/ActivityManager(158): 11% 158/system_server: 4.8% user + 6.4% kernel / faults: 2 minor
08-03 13:02:37.746: E/ActivityManager(158): 11% 192/InputDispatcher: 4.8% user + 6.4% kernel
08-03 13:02:37.746: E/ActivityManager(158): 1.6% 163/Compiler: 1.6% user + 0% kernel
08-03 13:02:37.746: E/ActivityManager(158): 1.6% 193/InputReader: 0% user + 1.6% kernel
08-03 13:02:37.746: E/ActivityManager(158): 18% TOTAL: 9.3% user + 9.3% kernel
so , yes , i think it's possible.