简述
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是不是我们自己写的。
效果
由于大部分都是照着大佬文章实现的,所以不做过多的解析。