在原来ANR-WatchDog的使用中,发现默认ANR阈值是5s,虽然可以自己设置这个阈值,但在主线程的消息队列里,ANR-WatchDog是直接sleep对应的阈值后才开始发消息,当我们需要同时处理block/anr异常时,异常信息里没有办法同时处理这两种信息,所以想如果可以同时报出block/anr以及对应的block时间到服务端,那服务端异常信息处理会更灵活,可以弹性决定是让业务同学处理block信息还是anr

博客原文地址http://www.coderlife.site/android/2018/08/20/extend-anr-watchdog.html

一.原有ANR-WatchDog的使用

1.新增依赖

app/build.gradle中新增

compile 'com.github.anrwatchdog:anrwatchdog:1.3.0'

2.初始化

new ANRWatchDog(5000).start();

3.异常统一处理

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

二.ANR-WatchDog改造

1.扩展回调接口

新增一个接口方法onAppNotResponding(boolean isAnr,int cost, ANRError error)

public interface ANRListener {
    public void onAppNotResponding(ANRError error);
    public void onAppNotResponding(boolean isAnr,int cost, ANRError error);
}

2.在发消息时判断是block信息还是anr信息

 @Override
public void run() {
    setName("|ANR-WatchDog|");

    int lastTick;
    int lastIgnored = -1;
    while (!isInterrupted()) {
        lastTick = _tick;
        _uiHandler.post(_ticker);
        try {
            Thread.sleep(_timeoutInterval);
            if (_blockTimeoutInterval!=0){
                Thread.sleep(_blockTimeoutInterval);
                timeOut += _blockTimeoutInterval;
                if (timeOut>=_anrTimeoutInterval){
                    isAnr = true;
                }
                cost = timeOut;
            } else {
                Thread.sleep(_timeoutInterval);
            }
        }
     }
}

3.使用举例

(1)实现一个BlockCallback,在onAppNotResponding中处理对应的异常信息

public class BlockCallback implements ANRWatchDog.ANRListener {

    @Override
    public void onAppNotResponding(ANRError error) {
        Log.e("BlockReport", "block cause: "
                + Arrays.toString(error.getCause().getStackTrace()));
    }

    @Override
    public void onAppNotResponding(boolean isAnr, int cost, ANRError error) {
        String type;
        if (isAnr){
            type = "anr";
        }else {
            type = "block";
        }
        Log.e("\nBlockReport", "type: " + type
                + "\nblock cost: " + cost + "ms"
                + "\nblock cause: "
                + Arrays.toString(error.getCause().getStackTrace()));
    }

}

(2)初始化
onCreate或者onActivityCreated阶段

new ANRWatchDog(500,5000).setIgnoreDebugger(true).setANRListener(new BlockCallback()).start();

三.源码地址

原来ANR-WatchDog的地址: https://github.com/SalomonBrys/ANR-WatchDog
二次开发后的源码地址: https://github.com/alexknight/ANR-WatchDog


↙↙↙阅读原文可查看相关链接,并与作者交流