Matrix源码分析(五)之 IdleHandlerLagTracer工作原理

从字面意思这个 IdleHandlerLagTracer 应该是监听 IdleHandler 的执行情况,不得不感叹Matrix功能做的是非常的细致,由于 IdleHandlerLagTracer 的代码量比较少,而且启动的重要成员的工作比较普通,我们先来介绍一下他的工作原理,再来看代码

IdleHandlerLagTracer 工作原理

1:IdleHandler 是Looper 的闲时机制,IdleHandlerLagTracer 会在开始工作后会启动一个 HandlerThread

2:使用反射将 MessageQueue 中承载着所有 IdleHandler 的 mIdleHandlers 这个 ArrayList 替换成自己的 新写的 MyArrayList ,这个这 MyArrayList 的add 和 remove 方法, 在调用 add 方法时,使用自己的 MyIdleHandler 作为中间层来传递事件,

3:在传递开始时使用绑定 HandlerThread 的 Handler 发送一个定时2s的延迟消息,如果2s后这个消息没有被移除,那么就会触发他的上报机制

在分析他的工作原理时将 IdleHandlerLagTracer 的整个工作流程分为了3部分,那么在分析源码的过程中,也使用这个流程

scss 复制代码
@Override
public void onAlive() {
    super.onAlive();
    if (traceConfig.isIdleHandlerTraceEnable()) {
        // 创建承载定时任务的 HandlerThread 
        idleHandlerLagHandlerThread = new HandlerThread("IdleHandlerLagThread");
        // 创建上报的任务,也就是定时2s后执行的任务
        idleHandlerLagRunnable = new IdleHandlerLagRunable();
        //反射 MessageQueue 中装在 IdleHandler 的 ArrayList
        detectIdleHandler();
    }
}

在开始先创建了一个 HandlerThread , 同时将上报的任务也创建了出来,最后在进行反射,来看看反射的情况

ini 复制代码
private static void detectIdleHandler() {
    try {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
            return;
        }
        MessageQueue mainQueue = Looper.getMainLooper().getQueue();
        Field field = MessageQueue.class.getDeclaredField("mIdleHandlers");
        field.setAccessible(true);
        MyArrayList<MessageQueue.IdleHandler> myIdleHandlerArrayList = new MyArrayList<>();
        field.set(mainQueue, myIdleHandlerArrayList);
        idleHandlerLagHandlerThread.start();
        idleHandlerLagHandler = new Handler(idleHandlerLagHandlerThread.getLooper());
    } catch (Throwable t) {
        MatrixLog.e(TAG, "reflect idle handler error = " + t.getMessage());
    }
}

这里也非常的细节,是在确定反射成功后才启动在前面创建的 HandlerThread ,其他的逻辑就是使用 MyArrayList 将 MessageQueue 中的 mIdleHandlers 替换一下 ,接下来继续看一下 MyArrayList 的封装逻辑

typescript 复制代码
static class MyArrayList<T> extends ArrayList {
    Map<MessageQueue.IdleHandler, MyIdleHandler> map = new HashMap<>();

    @Override
    public boolean add(Object o) {
        if (o instanceof MessageQueue.IdleHandler) {
            MyIdleHandler myIdleHandler = new MyIdleHandler((MessageQueue.IdleHandler) o);
            map.put((MessageQueue.IdleHandler) o, myIdleHandler);
            return super.add(myIdleHandler);
        }
        return super.add(o);
    }

    @Override
    public boolean remove(@Nullable Object o) {
        if (o instanceof MyIdleHandler) {
            MessageQueue.IdleHandler idleHandler = ((MyIdleHandler) o).idleHandler;
            map.remove(idleHandler);
            return super.remove(o);
        } else {
            MyIdleHandler myIdleHandler = map.remove(o);
            if (myIdleHandler != null) {
                return super.remove(myIdleHandler);
            }
            return super.remove(o);
        }
    }
}

在 MyArrayList 添加数据时,判断如果传入的数据类型是 MessageQueue.IdleHandler ,那么则使用 MyIdleHandler 包装一层,Matrix 玩这一套是真的6,在源码中随处可见的都是这种原理 ,再去看看 MyIdleHandler 都干了啥

java 复制代码
static class MyIdleHandler implements MessageQueue.IdleHandler {
    private final MessageQueue.IdleHandler idleHandler;

    MyIdleHandler(MessageQueue.IdleHandler idleHandler) {
        this.idleHandler = idleHandler;
    }

    @Override
    public boolean queueIdle() {
        idleHandlerLagHandler.postDelayed(idleHandlerLagRunnable, traceConfig.idleHandlerLagThreshold);
        boolean ret = this.idleHandler.queueIdle();
        idleHandlerLagHandler.removeCallbacks(idleHandlerLagRunnable);
        return ret;
    }
}

MyIdleHandler 中就是在开始转发任务前,先发送一个延时消息,在执行结束后移除这个定时消息,如果没有移除则触发这个消息的上报机制

到了这里整个工作就分析完成了

相关推荐
消失的旧时光-19431 天前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs1 天前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&1 天前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
LDORntKQH1 天前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2
android
冬奇Lab1 天前
Android 15 ServiceManager与Binder服务注册深度解析
android·源码·源码阅读
2501_916008891 天前
深入解析iOS机审4.3原理与混淆实战方法
android·java·开发语言·ios·小程序·uni-app·iphone
独行soc1 天前
2026年渗透测试面试题总结-20(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
常利兵1 天前
2026年,Android开发已死?不,它正迎来黄金时代!
android
Risehuxyc1 天前
备份三个PHP程序
android·开发语言·php
Doro再努力2 天前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim