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

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

相关推荐
耶叶1 小时前
Android 新权限申请模型(Activity Result API)
android
阿拉斯攀登1 小时前
【RK3576 安卓 JNI/NDK 系列 04】JNI 核心语法(下):字符串、数组与对象操作
android·驱动开发·rk3568·瑞芯微·rk安卓驱动·jni字符串操作
2501_915909061 小时前
不用越狱就看不到 iOS App 内部文件?使用 Keymob 查看和导出应用数据目录
android·ios·小程序·https·uni-app·iphone·webview
llxxyy卢1 小时前
web部分中等题目
android·前端
轩情吖1 小时前
MySQL之事务管理
android·后端·mysql·adb·事务·隔离性·原子性
万物得其道者成1 小时前
uni-app Android 离线打包:多环境(prod/dev)配置
android·opencv·uni-app
符哥20082 小时前
Firebase 官方提供的Quick Start-Android 库的功能集讲解
android
koeda2 小时前
android17系统兼容
android·安卓
进击的cc3 小时前
面试官:Handler 没消息时为啥不卡死?带你从源码到底层内核彻底整明白!
android·面试
Yang-Never3 小时前
OpenGL ES ->YUV图像基础知识
android·java·开发语言·kotlin·android studio