美文网首页Flutter飞起
Flutter aspectd (四) 全埋点实现

Flutter aspectd (四) 全埋点实现

作者: laomao_老毛 | 来源:发表于2021-06-23 10:30 被阅读0次

    简述

    aspectd的简单原理清楚了,下面尝试实现一下全埋点,参考大佬文章:
    Flutter之全埋点思考与实现

    获取到点击的按钮

     @Execute("package:flutter/src/gestures/binding.dart", "GestureBinding",
          "-dispatchEvent")
      @pragma("vm:entry-point")
      dynamic hookHitTest(PointCut pointCut) {
        PointerEvent pointEvent = pointCut.positionalParams[0];
        HitTestResult hitTestResult = pointCut.positionalParams[1];
        if (pointEvent is PointerUpEvent) {
          HookImpl.getInstance().hookHitTest(hitTestResult.path.first, pointEvent);
        }
        return pointCut.proceed();
      }
    

    上面是通过拦截,GestureBinding的dispatchEvent方法,获取到传给该方法的PointerEvent和HitTestResult参数。

    拦截点击事件

      @Execute("package:flutter/src/gestures/recognizer.dart", "GestureRecognizer",
          "-invokeCallback")
      @pragma("vm:entry-point")
      dynamic hookInvokeCallback(PointCut pointCut) {
        dynamic result = pointCut.proceed();
        dynamic eventName = pointCut.positionalParams[0];
        print("GestureRecognizer:::::invokeCallback");
        HookImpl.getInstance().hookClick(eventName);
        return result;
      }
    

    拦截GestureRecognizer中的invokeCallback方法,可以通过传递的参数,得到是不是点击状态,判断eventName == "onTap"

     void hookClick(String eventName) {
        if (eventName == "onTap") {
          initValues();
          _getElementPath();
          _getElementType();
          _getElementContent();
          _printClick(elementInfoMap);
          _resetValues();
        }
      }
    

    定位一个Widget是否是自己写的

    可以参照Flutter的track_widget_constructor_locations类进行更改,所在位置:

    kernel/transformations/track_widget_constructor_locations.dart
    

    对该类的更改:

    // 判断当导入类中有我们定义的类的时候
    if (importUri.path.contains('hook_impl.dart')) {
        for (Class class_ in library.classes) {
            // 获取到所有的类,如果有_CustomHasCreationLocation,那么把_hasCreationLocationClass赋值为_CustomHasCreationLocation,下面同理
          if (class_.name == '_CustomHasCreationLocation') {
            _hasCreationLocationClass = class_;
          } else if (class_.name == '_CustomLocation') {
            _locationClass = class_;
          }
        }
      }
    

    再看看_hasCreationLocationClass做了什么

     void _transformClassImplementingWidget(Class clazz) {
        // 这里是给我们写的组件加了一个SuperType _CustomHasCreationLocation
        clazz.implementedTypes
            .add(new Supertype(_hasCreationLocationClass, <DartType>[]));
    }
    

    这样我们就可以通过判断Widget是不是_CustomHasCreationLocation类型,就能知道这个Widget是不是我们自己写的。

    效果

    由于大部分都是照着大佬文章实现的,所以不做过多的解析。

    image

    githbu地址

    相关文章

      网友评论

        本文标题:Flutter aspectd (四) 全埋点实现

        本文链接:https://www.haomeiwen.com/subject/yptbyltx.html