Open tprochazka opened 5 years ago
Another weird thing is that timeout in the constructor is int
, but time in ANRInterceptor
is Long.
Oh, it helped me figure out why obvious Thread.sleep(7000)
is not caught sometimes...
Ended up with:
new ANRWatchDog(500)
.setANRInterceptor(new ANRWatchDog.ANRInterceptor() {
private long lastReportTs = 0L;
@Override
public long intercept(long duration) {
if (duration >= 2500L && System.currentTimeMillis() - lastReportTs > duration) {
final IllegalStateException exception = new IllegalStateException("ANR");
final Thread mainThread = Looper.getMainLooper().getThread();
exception.setStackTrace(mainThread.getStackTrace());
Log.e("ANRWatchDog",
"ANR is detected",
exception
);
lastReportTs = System.currentTimeMillis();
}
return Math.min(5000L - duration, 500L);
}
})
.setANRListener(error -> {
Log.e("ANRWatchDog",
"ANR is detected",
error
);
})
.start();
I tested your library and I found that reaction on ANR is much bigger than the value set in constructor by
new ANRWatchDog(10000 /*timeout*/).start();
I found that it is caused by this code
If there is no ANR, your thread basically sleeps for 10000 ms in this case. During this 10s can happen that thread is blocked, for example in the middle. So it is already 5s blocked at the end, but tick has arrived before it happens. So it will sleep again 10s, and then it detects ANR after 15s. So theoretically it can be almost double of configured time.
The only workaround is to use low timeout interval, for example, 500ms And then use
ANRInterceptor
and detect real 10s here.But this behavior is not clear from the documentation.