StrictANR 实现机制
2017-02-06 本文已影响40人
ahking17
实现机制
在子线程中, 得到主线程的handler, 在run()中, 先发一个runnable让主线程去执行, 然后sleep()设定的时间, 然后再检测int _tick的值是否被修改了, 这个runnable的目的就是改变int _tick的值, 如果_tick的值没有得到修改, 就说明发生了strict anr.
public class StrictANRWatchDog extends Thread {
private final Handler _uiHandler = new Handler(Looper.getMainLooper());
private final int _timeoutInterval;
private volatile int _tick = 0;
public StrictANRWatchDog(int timeoutInterval) {
super();
_timeoutInterval = timeoutInterval;
}
private final Runnable _ticker = new Runnable() {
@Override public void run() {
_tick = (_tick + 1) % Integer.MAX_VALUE;
}
};
//这个runnable对象的目的, 就是让保证int _tick的值发生了改变.
public interface ANRListener {
public void onAppNotResponding(StrictANRError error);
}
@Override
public void run() {
setName("|Strict-ANR-WatchDog|");
int lastTick;
int lastIgnored = -1;
while (!isInterrupted() && _keepTracking) {
lastTick = _tick;
_uiHandler.post(_ticker);
//向主线程的handler发送一个runnable对象去执行.
try {
Thread.sleep(_timeoutInterval);
//sleep设定的时间
}
catch (InterruptedException e) {
_interruptionListener.onInterrupted(e);
return ;
}
//如果int _tick的值没有发生改变, 说明发送给主线程的runnable没有得到及时的执行, 也就是发生了strict anr.
// If the main thread has not handled _ticker, it is blocked. ANR.
if (_tick == lastTick) {
StrictANRError error;
if (_namePrefix != null)
error = new StrictANRError(_namePrefix, _logThreadsWithoutStackTrace);
else
error = StrictANRError.NewMainOnly();
_anrListener.onAppNotResponding(error);
}
}
JLog.i("exit Strict ANR WatchDog thread.");
}
public void startTracking() {
if(this.isAlive()) {
return;
}
_keepTracking = true;
start();
}
}
使用上很简单
在Application onCreate()中, 创建StrictANRWatchDog 的对象, 并开始检测就可以了.
private void initStrictANRWatchDog() {
mWatchDog = new StrictANRWatchDog(mTimeInterval);
mWatchDog.setANRListener(new StrictANRWatchDog.ANRListener() {
@Override
public void onAppNotResponding(StrictANRError error) {
JLog.i("Strict ANR detected.");
Message msg = new Message();
msg.what = MSG_TOAST;
msg.obj = "Strict ANR detected.";
mHandler.sendMessage(msg);
error.printAllStackTrace();
}
});
mWatchDog.startTracking();
}
-----DONE.--------------------------