Matrix源码分析(二)之 LooperAnrTracer工作原理

LooperAnrTracer 工作原理

在非主线程Looper 中创建2个Handler , 在每次 主线程中的Looper 开始处理消息时 post 延迟的callback ,如果到达对应的时间节点后,主线程的Looper 没有执行完消息,也就没有将 其他Looper post 的callback移除,导致开始收集信息,

java 复制代码
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 中,比较难以理解的就是 下面的部分了

arduino 复制代码
// 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();
            }
        }
    });
}

但是关于这部分还是慢方法中相关的内容,具体的介绍我会在后续的博客内容中介绍到,

相关推荐
2601_949833395 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
2603_949462107 小时前
Flutter for OpenHarmony社团管理App实战:预算管理实现
android·javascript·flutter
王泰虎9 小时前
安卓开发日记,因为JCenter 关闭导致加载不了三方库应该怎么办
android
2601_9495430112 小时前
Flutter for OpenHarmony垃圾分类指南App实战:主题配置实现
android·flutter
2601_9498333914 小时前
flutter_for_openharmony口腔护理app实战+知识实现
android·javascript·flutter
晚霞的不甘14 小时前
Flutter for OpenHarmony从基础到专业:深度解析新版番茄钟的倒计时优化
android·flutter·ui·正则表达式·前端框架·鸿蒙
鸟儿不吃草14 小时前
android的Retrofit请求https://192.168.43.73:8080/报错:Handshake failed
android·retrofit
Minilinux201814 小时前
Android音频系列(09)-AudioPolicyManager代码解析
android·音视频·apm·audiopolicy·音频策略
李子红了时15 小时前
【无标题】
android
Android系统攻城狮16 小时前
Android tinyalsa深度解析之pcm_close调用流程与实战(一百零四)
android·pcm·tinyalsa·音频进阶·音频性能实战·android hal