簡(jiǎn)述
aspectd的簡(jiǎn)單原理清楚了凿傅,下面嘗試實(shí)現(xiàn)一下全埋點(diǎn),參考大佬文章:
Flutter之全埋點(diǎn)思考與實(shí)現(xiàn)
獲取到點(diǎn)擊的按鈕
@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參數(shù)。
攔截點(diǎn)擊事件
@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方法虐急,可以通過傳遞的參數(shù)箱残,得到是不是點(diǎn)擊狀態(tài),判斷eventName == "onTap"
void hookClick(String eventName) {
if (eventName == "onTap") {
initValues();
_getElementPath();
_getElementType();
_getElementContent();
_printClick(elementInfoMap);
_resetValues();
}
}
定位一個(gè)Widget是否是自己寫的
可以參照Flutter的track_widget_constructor_locations類進(jìn)行更改戏仓,所在位置:
kernel/transformations/track_widget_constructor_locations.dart
對(duì)該類的更改:
// 判斷當(dāng)導(dǎo)入類中有我們定義的類的時(shí)候
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) {
// 這里是給我們寫的組件加了一個(gè)SuperType _CustomHasCreationLocation
clazz.implementedTypes
.add(new Supertype(_hasCreationLocationClass, <DartType>[]));
}
這樣我們就可以通過判斷Widget是不是_CustomHasCreationLocation類型敷待,就能知道這個(gè)Widget是不是我們自己寫的。
效果
由于大部分都是照著大佬文章實(shí)現(xiàn)的仁热,所以不做過多的解析榜揖。