自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img

img
img
htt

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

构造方法

构造方法仅仅是拿到了传入的配置,配置中包含的是IdleHandler监控是否启用的开关,isIdleHandlerTraceEnable。

public IdleHandlerLagTracer(TraceConfig config) {
    traceConfig = config;
}

onStartTrace

onStartTrace会调用到onAlive方法,我们看onAlive的源码,首先初始化了一个HandlerThread,然后创建了一个IdleHandlerLagRunnable,最后调用了detectIdleHandler开启监控。

@Override
public void onAlive() {
    super.onAlive();
    if (traceConfig.isIdleHandlerTraceEnable()) {
        //异步线程
        idleHandlerLagHandlerThread = new HandlerThread("IdleHandlerLagThread");
        //上报信息用的runnable
        idleHandlerLagRunnable = new IdleHandlerLagRunable();
        detectIdleHandler();
    }
}

IdleHandlerLagRunnable是用于上报信息的,我们先看detectIdleHandler方法。首先拿到主线程消息队列对象,然后通过反射从MessageQueue对象上获取到mIdleHandlers的Field对象,mIdleHandlers是一个List集合,内部存储了所有当前消息队列添加的IdleHandler对象。拿到之后构造了一个自定义的List-MyArrayList,反射将其设置到消息队列上,这里的目的是将mIdleHandlers作为一个hook点,完成替换之后,主线程添加和移除IdleHandler的操作都在我们的监控范围之内了。

private static void detectIdleHandler() {
    MessageQueue mainQueue = Looper.getMainLooper().getQueue();
    Field field = MessageQueue.class.getDeclaredField("mIdleHandlers");
    field.setAccessible(true);
    MyArrayList<MessageQueue.IdleHandler> myIdleHandlerArrayList = new MyArrayList<>();
    //反射替换消息队列中的List
    field.set(mainQueue, myIdleHandlerArrayList);
    idleHandlerLagHandlerThread.start();
    idleHandlerLagHandler = new Handler(idleHandlerLagHandlerThread.getLooper());
}

MyArrayList

看下MyArrayList的实现。它继承自ArrayList,重写了add和remove方法,也就是拦截了IdleHandler的添加和移除。当通过调用MessageQueue的addIdleHandler方法向list中添加时,就会走到MyArrayList的add方法中,此时会将IdleHandler再包装一层MyIdleHandler存入,达到拦截IdleHandler的queueIdle方法调用的目的。

static class MyArrayList<T> extends ArrayList {
    Map<MessageQueue.IdleHandler, MyIdleHandler> map = new HashMap<>();
    @Override
    public boolean add(Object o) {
        if (o instanceof MessageQueue.IdleHandler) {
            //包装一层,作为代理。拦截queueIdle方法的执行
            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);
       }
   }
}

MyIdleHandler

接下来我们看看MyIdleHandler是怎么实现的。可以看到它继承自IdleHandler,并重写了它的queueIdle方法,这样一来每一个IdleHandler执行时都会走到MyIdleHandler的queueIdle方法中,也就都在我们的监控之内了。

static class MyIdleHandler implements MessageQueue.IdleHandler {
    @Override
    public boolean queueIdle() {
        //发送延时消息,延时内未执行完成就上报
        idleHandlerLagHandler.postDelayed(idleHandlerLagRunnable, traceConfig.idleHandlerLagThreshold);
        boolean ret = this.idleHandler.queueIdle();
        //执行完成则移除延时消息
        idleHandlerLagHandler.removeCallbacks(idleHandlerLagRunnable);
        return ret;
    }
}

当queueIdle执行的时候,通过idleHandlerLagHandler发送一个延时2s(默认)的消息,idleHandlerLagHandler是一个和HandlerThread绑定的Handler,它会将消息发送到HandlerThread子线程执行,假如2s内queueIdle方法执行完成,那么这个消息就会被移除,也就是不会触发上报。

这个消息做了什么呢?我们接下来看看这个idleHandlerLagRunnable。

IdleHandlerLagRunnable

这里也就是在收集信息上报了。

static class IdleHandlerLagRunable implements Runnable {
    @Override
    public void run() {
        String stackTrace = Utils.getMainThreadJavaStackTrace();
        boolean currentForeground = AppForegroundUtil.isInterestingToUser();
        String scene = AppActiveMatrixDelegate.INSTANCE.getVisibleScene();
        JSONObject jsonObject = new JSONObject();
        jsonObject = DeviceUtil.getDeviceInfo(jsonObject, Matrix.with().getApplication());
        jsonObject.put(SharePluginInfo.ISSUE_STACK_TYPE, Constants.Type.LAG_IDLE_HANDLER);             jsonObject.put(SharePluginInfo.ISSUE_SCENE, scene);
        jsonObject.put(SharePluginInfo.ISSUE_THREAD_STACK, stackTrace);
        jsonObject.put(SharePluginInfo.ISSUE_PROCESS_FOREGROUND, currentForeground);
e);
        jsonObject.put(SharePluginInfo.ISSUE_THREAD_STACK, stackTrace);
        jsonObject.put(SharePluginInfo.ISSUE_PROCESS_FOREGROUND, currentForeground);
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐