Flutter—— 一個有意思的工具:行為錄製器 behavior_recorder
theme: smartblue
我正在參加跨端技術專題徵文活動,詳情檢視:juejin.cn/post/710123…
前言
此工具提供使用者行為(手勢
、文字輸入
)的錄製及回放,同時支援記錄的匯出和匯入。
例如,可以由測試人員進行bug復現步驟
的錄製及上傳,並由對應開發人員下載匯出再重放。當然也可以用於線上使用者的反饋。
Tip:
1.此工具目前支援 flutter 2.5.3-null-safety,
->如果是其他版本的flutter可以檢視Beike_AspectD是否支援,或者自行fork進行相關適配即可
2.動圖可能有點兒大。
行為的錄製和回放
行為記錄的匯出、匯入及回放
實現
兩種行為的錄製都是基於hook實現的, 這裡做一下簡單介紹。
手勢錄製及回放
錄製
手勢的錄製通過hook GestureBinding
的-handlePointerEvent
方法,對平臺端所傳遞過來的pointer event
進行轉換並生成PointerEventBundle
儲存在佇列中。
void _hookHandlePointerEvent(PointCut pointCut) {
gestureRecorder.handleHook(pointCut);
pointCut.proceed();
}
```
class GestureRecorder extends Recorder
///...其它程式碼
@override void handleHook(PointCut pointCut) { if(pointCut.positionalParams.isEmpty) { return; } startTime ??= timeStamp; final event = pointCut.positionalParams.first; _cacheBucket.add(event); if(event is PointerUpEvent || event is PointerCancelEvent) { final int endTime = DateTime.now().millisecondsSinceEpoch; enqueue(PointerEventBundle.load(startTime!, endTime, type, Queue.from(_cacheBucket))); startTime = null; _cacheBucket.clear(); } }
@override SourceType get type => SourceType.gesture;
} ```
回放
PointerEventBundle
內部儲存原始的pointer event(佇列形式)
,只需將它們按序傳遞給GestureBinding
的handlePointerEvent
方法即可實現回放。
@override
Future perform() async {
while(_eventQueue.isNotEmpty) {
await WidgetsBinding.instance?.endOfFrame;
GestureBinding.instance?.handlePointerEvent(_eventQueue.removeFirst());
}
return Future.value();
}
文字輸入的錄製和回放
錄製
文字輸入的錄製是通過hookTextInput
的 _handleTextInputInvocation
方法,對平臺端所傳遞的文字輸入事件
進行轉換,並生成TextInputEventBundle
儲存在佇列中。
```
class TextInputRecorder extends Recorder
///...其它程式碼
@override void handleHook(PointCut pointCut) { if(pointCut.positionalParams.isEmpty) { return; } final int startTime = DateTime.now().millisecondsSinceEpoch; final methodCall = pointCut.positionalParams.first; if(methodCall is MethodCall && methodCall.arguments is List) { final list = methodCall.arguments as List; if(list.isNotEmpty) { id = list.first; } } final int endTime = DateTime.now().millisecondsSinceEpoch; enqueue(TextInputEventBundle(startTime, endTime, type, methodCall)); }
} ```
回放
文字輸入事件
的回放與上面大致相同:
1. 首先我們將`TextInputEventBundle`內部儲存的事件物件,
通過SystemChannels.textInput.codec編碼器轉化為 bytedata
2. 之後,將bytedata交給ServicesBinding.instance?
.defaultBinaryMessenger
.handlePlatformMessage方法即可
@override
Future perform() async {
_updateRecord();
final bytedata = SystemChannels.textInput.codec.encodeMethodCall(methodCall);
ServicesBinding.instance?.defaultBinaryMessenger
.handlePlatformMessage(SystemChannels.textInput.name, bytedata, null);
return Future.value();
}
功能介紹
首先新增 import 'package:behavior_recorder_of_kit/behavior_recorder_of_kit.dart';
到main.dart
檔案。
錄製和播放
通過 RecordPlayer().startRecord()
開始錄製,以及RecordPlayer().finishRecord()
結束錄製。
錄製結束後,通過 RecordPlayer().play();
進行重播。
Tip: 所錄製的行為事件是一次性的,即:在播放後將會失效。
如果需要重複播放,可以考慮通過RecordPlayer().exportTape()將事件匯出。
記錄的匯出和匯入
如果需要將錄製的記錄匯出,可以通過 RecordPlayer().exportTape()
方法。
Tip: 匯出後的序列化方式需要自行定義。
當我們需要從外部匯入行為記錄時,可以通過 RecordPlayer().loadRecords();
方法:
``` //匯入錄製前,要開啟錄製功能 RecordPlayer().startRecord(); while(cache.isNotEmpty) { RecordPlayer().loadRecords(cache.removeFirst()); } //結束匯入後,建議關閉錄製。 RecordPlayer().finishRecord();
//之後通過下方法即可播放記錄。
RecordPlayer().play()
```
其它用法,可以見專案的Readme
, 謝謝閱讀。
專案地址:
其它文章
- Flutter—— 一個有意思的工具:行為錄製器 behavior_recorder
- Flutter——平臺通訊記錄器 : channel_observer
- 【翻譯】識別&處理Android構建時的記憶體問題
- Flutter&Flame在遊戲上的實踐——坦克大戰
- Flutter跨程序混合棧渲染的實踐——子程序WebView
- Flutter在Android平臺上啟動時,Native層做了什麼?
- Flutter——在Android平臺上的啟動流程淺析
- Flutter&Android 啟動頁(閃屏頁)的載入流程和優化方案
- Flutter 實現應用內部的自定義widget通知功能
- Flutter入門——設計實現一個自定義Widget的彈出工具
- Flutter——Hybrid Composition混合圖層的原理分析
- Flutter&Bedrock框架——頁面的區域性重新整理介紹
- Flutter——仿.知乎列表的視差效果
- Flutter入門——Widget、Element和RenderObject的由來
- Flutter入門練習——Evenet&Method Channel協作載入大圖
- Flutter——ListView原始碼分析之child-view的構建
- Flutter——實現網易雲音樂的滑動衝突處理效果
- Flutter動畫入門—— 內外逆向環Loading動畫
- Flutter——實現網易雲音樂的漸進式卡片切換
- Flutter——實現網易雲音樂的Tabbar切換效果