addTransientCallbacks method
void
addTransientCallbacks()
首先,我希望所有的任务都在构建前进行统一处理, 1.所以要么在build中添加hook来拿到这个时间节点,而且在build中hook的方式必须触发build才行 2.要么就是在build之前,layout之后,同理可以在layout之后,或者paint过程中添加hook 3.要么就是添加到微任务队列中,没有任何hook的方式,如果在动画阶段,添加的话没有任何问题 如果在idle阶段,则添加的微任务会在build和layout之前触发,不满足需求
Implementation
void addTransientCallbacks() {
mtLog("addTransientCallbacks");
if (hasAddTransitentCallback) {
return;
}
hasAddTransitentCallback = true;
int beginFrame = FrameUtil.frameCount;
// ignore: unused_local_variable
final stackTrace = StackTrace.current;
/// 如果由动画触发的添加任务,并且之后异步任务请求是同步完成的,那么就是transientCallbacks阶段
/// transientCallbacks阶段添加transientCallback任务不会在当地立即触了,必须等到下一帧才行
/// 因此会出现即使是同步任务,仍然非同帧加载
final phase = FrameUtil.phase;
WidgetsBinding.instance.scheduleFrameCallback((timeStamp) {
mtLog("scheduleFrameCallback");
int transitentFrame = FrameUtil.frameCount;
Future.microtask(() {
int micFrame = FrameUtil.frameCount;
assert(() {
if (beginFrame == transitentFrame && beginFrame == micFrame) {
/// 只有最初的任务是build阶段触发,所以可能会出现微任务发生在下一帧
/// 但是我们在添加任务的时候做一下处理即可。
return true;
} else {
assert(phase == SchedulerPhase.transientCallbacks, "先不考虑mid微任务阶段");
return true;
}
// return false;
}(), "应该是完全一致的");
// try {
mtLog("微任务modifyDataAndCorrectPixelCallback处理之前", tag: TagsConfig.tagTestMicroQues);
infiniteScorllController.modifyDataAndCorrectPixelCallback();
mtLog("微任务modifyDataAndCorrectPixelCallback处理之后", tag: TagsConfig.tagTestMicroQues);
// } catch (e) {
// /// TODO 如何比较好的处理进入时间循环的堆栈信息呢?
// mtLog("(((------");
// mtLog(e);
// debugPrintStack(stackTrace: stackTrace, maxFrames: 10, label: "未捕获到的错误");
// mtLog("------)))");
// assert(false);
// rethrow;
// }
});
});
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
hasAddTransitentCallback = false;
});
}