LooperAnrTracer 工作原理
在非主线程Looper 中创建2个Handler , 在每次 主线程中的Looper 开始处理消息时 post 延迟的callback ,如果到达对应的时间节点后,主线程的Looper 没有执行完消息,也就没有将 其他Looper post 的callback移除,导致开始收集信息,
public class LooperAnrTracer extends Tracer implements ILooperListener {
private static final String TAG = "Matrix.AnrTracer";
private Handler anrHandler;
private Handler lagHandler;
private final TraceConfig traceConfig;
private final AnrHandleTask anrTask = new AnrHandleTask();
private final LagHandleTask lagTask = new LagHandleTask();
private final boolean isAnrTraceEnable;
public LooperAnrTracer(TraceConfig traceConfig) {
this.traceConfig = traceConfig;
this.isAnrTraceEnable = traceConfig.isAnrTraceEnable();
}
@Override
public void onAlive() {
super.onAlive();
if (isAnrTraceEnable) {
LooperMonitor.register(this);
this.anrHandler = new Handler(MatrixHandlerThread.getDefaultHandler().getLooper());
this.lagHandler = new Handler(MatrixHandlerThread.getDefaultHandler().getLooper());
}
}
@Override
public void onDead() {
super.onDead();
if (isAnrTraceEnable) {
LooperMonitor.unregister(this);
anrTask.getBeginRecord().release();
anrHandler.removeCallbacksAndMessages(null);
lagHandler.removeCallbacksAndMessages(null);
}
}
@Override
public boolean isValid() {
return true;
}
// 主线程Looper 开始处理消息,在自定义Looper 中发送延迟消息
@Override
public void onDispatchBegin(String log) {
anrTask.beginRecord = AppMethodBeat.getInstance().maskIndex("AnrTracer#dispatchBegin");
if (traceConfig.isDevEnv()) {
MatrixLog.v(TAG, "* [dispatchBegin] index:%s", anrTask.beginRecord.index);
}
anrHandler.postDelayed(anrTask, Constants.DEFAULT_ANR);
lagHandler.postDelayed(lagTask, Constants.DEFAULT_NORMAL_LAG);
}
// 主线程Looper 结束处理消息,移除 自定义Looper 定时消息
@Override
public void onDispatchEnd(String log, long beginNs, long endNs) {
if (traceConfig.isDevEnv()) {
long cost = (endNs - beginNs) / Constants.TIME_MILLIS_TO_NANO;
MatrixLog.v(TAG, "[dispatchEnd] beginNs:%s endNs:%s cost:%sms", beginNs, endNs, cost);
}
anrTask.getBeginRecord().release();
anrHandler.removeCallbacks(anrTask);
lagHandler.removeCallbacks(lagTask);
}
}
在整个 LooperAnrTracer 中,比较难以理解的就是 下面的部分了
// trace
LinkedList<MethodItem> stack = new LinkedList<>();
if (data.length > 0) {
TraceDataUtils.structuredDataToStack(data, stack, true, curTime);
TraceDataUtils.trimStack(stack, Constants.TARGET_EVIL_METHOD_STACK, new TraceDataUtils.IStructuredDataFilter() {
@Override
public boolean isFilter(long during, int filterCount) {
return during < (long) filterCount * Constants.TIME_UPDATE_CYCLE_MS;
}
@Override
public int getFilterMaxCount() {
return Constants.FILTER_STACK_MAX_COUNT;
}
@Override
public void fallback(List<MethodItem> stack, int size) {
MatrixLog.w(TAG, "[fallback] size:%s targetSize:%s stack:%s", size, Constants.TARGET_EVIL_METHOD_STACK, stack);
Iterator<MethodItem> iterator = stack.listIterator(Math.min(size, Constants.TARGET_EVIL_METHOD_STACK));
while (iterator.hasNext()) {
iterator.next();
iterator.remove();
}
}
});
}
但是关于这部分还是慢方法中相关的内容,具体的介绍我会在后续的博客内容中介绍到,