友盟统计ANR

今天在测试app的时候,发现有一个地方一直在报ANR,没有定位到具体代码。

通过网上资料写了一个方法,去监听代码里面超时的地方,抛出异常进行定位。

具体如下:

public class ANRWatchDog extends Thread {
    public static final int MESSAGE_WATCHDOG_TIME_TICK = 0;
    /**
     * 判定Activity发生了ANR的时间,必须要小于5秒,否则等弹出ANR,可能就被用户立即杀死了。
     */
    public static final int ACTIVITY_ANR_TIMEOUT = 2000;
    private static int lastTimeTick = -1;
    private static int timeTick = 0;
    private Handler watchDogHandler = new android.os.Handler() {
        @Override
        public void handleMessage(Message msg) {
            timeTick++;
            timeTick = timeTick % Integer.MAX_VALUE;
        }
    };

    @Override
    public void run() {
        while (true) {
            watchDogHandler.sendEmptyMessage(MESSAGE_WATCHDOG_TIME_TICK);
            try {
                Thread.sleep(ACTIVITY_ANR_TIMEOUT);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //如果相等,说明过了ACTIVITY_ANR_TIMEOUT的时间后watchDogHandler仍没有处理消息,已经ANR了
            if (timeTick == lastTimeTick) {
                throw new ANRException();
            } else {
                lastTimeTick = timeTick;
            }
        }
    }
    public class ANRException extends RuntimeException {
        public ANRException() {
            super("应用程序无响应,快来改BUG啊!!");
            Thread mainThread = Looper.getMainLooper().getThread();
            setStackTrace(mainThread.getStackTrace());
        }
    }

}

然后在的Application中将该类初始化。

系统内存在超时的地方,就会抛出异常,并帮你定位。

我的情况是在使用友盟统计的时候,在Activity中调用onKillProcess这个方法。

onKillProcess是在app内杀死进程的时候(如 Process.kil,System.exit)进行调用的方法,主要是保存一些页面调用的数据。正常的应用是不需要调用此方法的。因为保存的时候耗时太长,所以ANR了。

所以在使用onKillProcess的时候切忌,使用在正确的位置。

猜你喜欢

转载自blog.csdn.net/qq_33240767/article/details/80581580