在FlutterEngine的构造函数的调用链中,会执行startInitialization(Context,Settings)@FlutterLoader.java
public void startInitialization(Context applicationContext, Settings settings){
...
VsyncWaiter.getInstance((WindowManager)applicationContext.getSystemService(Context.WINDOW_SERVICE)).init();
...
}
@VsyncWaiter.java
private final FlutterJNI.AsyncWaitForVsyncDelegate asyncWaitForVsyncDelegate = new FlutterJNI.AsyncWaitForVsyncDelegate(){
public void asyncWaitForVsync(long cookie){
Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback(){
public void doFrame(long frameTimeNanos){
...
FlutterJNI.nativeOnVsync(frameTimeNanos, frameTimeNanos+refreshPeriodNanos, cookie);
}
});
}
}
public void init(){
FlutterJNI.setAsyncWaitForVsyncDelegate(asyncWaitForVsyncDelegate);
...
}
来看FlutterJNI对于这个asyncWaitForVsyncDelegate的使用
@FlutterJNI.java
//Called by native
private static void asyncWaitForVsync(final long cookie){
if(asyncWaitForVsyncDelegate != null){
asyncWaitForVsyncDelegate.asyncWaitForVsync(cookie);
}
}
public static native void nativeOnVsync(long frameTimeNanos, long frameTargetTimeNanos, long cookie);
上面对于asyncWaitForVsync()的那句注释Calledbynative是Flutter原始注释,说明这个方法会在某个native节点进行调用。
该native方法是注册啊vsync_wait_android.cc中[engine源码],对应的方法为onNativeVsync()
现在假定它被调用了。
//./shell/platform/android/vsync_waiter_android.cc
void VsyncWaiterAndroid::OnNativeVsync(JNIEnv* env, jclass jcaller, jlong frameTimeNanos, jlong frameTargetTimeNanos, jlong java_baton){
...
ConsumePendingCallback(java_baton, frame_time, target_time);
}
void VsyncWaiterAndroid::ConsumePendingCallback(jlong java_baton, fml::TimePoint frame_start_time, fml::TimePoint frame_target_time){
...
//VsyncWaiter类
shared_this->FireCallback(frame_start_time, frame_target_time);
}
//vsync_waiter.cc
void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, fml_TimePoint frame_target_time){
Callback callback=std::move(callback_);
...
task_runners.GetUITaskRunner()->PostTakForTime(
[callback, flow_identifier, frame_start_time, frame_start_time](){
callback(frame_start_time, frame_target_time);
},frame_start_time);
)
}
上面就是将callback 抛到UI线程进行执行,callback_是在VsyncWaiter::AsyncWaitForVsync(Callback)中进行赋值,而该函数在animatior.cc中进行调用
//animatior.cc
void Animator::AwaitVSync(){
waiter_->AsyncWaitForVsync([self=weak_factory_.GetWeakPtr()](fml::TimePoint frame_start_time, fml::TimePoint frame_target_time){
//这里是self就是animator对象
if(self){
if(self->CanReuseLastLayerTree()){
self->DrawLastLayerTree();
}else{
self->BeginFrame(frame_start_time, frame_target_time);
}
}
});
AwaitVsync();
}
这里需要提一句,Animator::AwaitVsync()是在由Animator:RequestFrame()调用,而后者是在Engine::ScheduleFrame()调用。
这里的AwaitVsync()指向VsyncWaiterAndroid::AwaitVsync();
//vsync_waiter_android.cc
void VsyncWaiterAndroid::AwaitSync(){
...
task_runners_.GetPlatformTaskRunner()->PostTask([java_baton](){
JNIEnv* env = fml::jni::AttachCurrentThread();
//从该类不难得出,该方法反射调用asyncWaitForVsync()@FluuterJNI.java,即我们分析的源头。
env->CallStaicVoidMethod(g_vsync_waiter_class->obj(), g_async_wait_for_vsync_method_, java_baton);
});
}
现在有一环跑通了,从Engine::.scheduleFrame()到Animator::RequestFrame()到Animator::AwaitVsync()其实就是注册这个VSYNC回调的过程,而每次执行完self->DrawLastLayerTree()或self->BeginFrame()后,又重新注册vsync,即每次VSYNC到来(不发生掉帧)都会进行一次回调Animator::DrawLastLayerTree()或Animator::BeginFrame(),Animator::DrawLastLayerTree()就是绘制上一次的视图,现在重点看Animator::BeginFrame();
//animator.cc
void Animator::BeginFrame(fml::TimePoint frame_start_time, fml::TimePoint frame_target_time){
...
//delegate_为shell.cc对象
delegate_.onAnimatorBeginFrame(last_begin_frame_time_);
}
//shell.cc
void Shell::OnAnimatorBeginFrame(fml::TimePoint frame_time){
engine_->BeginFrame(frame_time);
}
//engine.cc
void Engine::BeginFrame(fml::TimePoint frame_time){
runtime_control_->BeginFrame(frame_time);
}
//runtime_controller.cc
bool RuntimeController::BeginFrame(fml::TimePoint frame_time){
window->BeginFrame(frame_time);
}
//window.cc
void Window::BeginFrame(fml::TimePoint frameTime){
//该反射会调用onBeginFrame()@window.dart
tonic::DartInvokeFiled(library_.value(), "_beginFrame",{Dart_NewInteger(microseconds),}));
//执行microtask
UIDartState::Current()->FlushMicrotaskNow();
//该反射会调用onDrawFrame()@window.dart
tonic::DartInvokeField(library_.value(),"_drawFrame",{})';
}
可以看到microtask位于beginFrame和drawFrame之间,耗时会影响ui绘制。
//hooks.dart
@pragma('vm:entry-point')
void _beginFrame(int microseconds){
_invoke1<Duration>(window.onBeginFrame, window._onBeginFrameZone, Duration(microseconds:microseconds));
}
@pragma('vm:entry-point')
void _drawFrame(){
_invoke(window.onDrawFrame, window._onDrawFrameZone);
}
window.onBeginFrame与onDrawFrame在ScheduleBinding(binding.dart中注册),在flutter_run_app_analyze中已经有提及了,
//scheduler/binding.dart
void _handleBeginFrame(Duration rawTimeStamp){
handleBeginFrame(rawTimeStamp);
}
void _handleDrawFrame(){
handleDrawFrame(rawTimeStamp);
}
关于handleBeginFrame()与handleDrawFrame()另外其文章分析。
网友评论