Flutter 3.3.10
flutter android embedding 1.0.0
关键类
FlutterActivity
FlutterFragment
FlutterFragmentActivity
FlutterView
FlutterEngine
FlutterRender
FlutterJNI
FlutterActivity#onCreate() 函数里创建FlutterView对象并setContentView
FlutterView里的成员变量renderSurface指向的是三种view的一种,FlutterSurfaceView、
FlutterTextureView、FlutterImageView
如果是FlutterSurfaceView则在SurfaceHolder.Callback#surfaceCreated()回调函数里最终调用native函数FlutterJNI#nativeSurfaceCreated(long nativeShellHolderId, @NonNull Surface surface)
实现给flutter engine送android应用端的Surface,这是获取SurfaceFlinger分配的GraphicBuffer代理类,属于图形缓冲区的生产者
如果FlutterView里的成员变量renderSurface指向的是FlutterSurfaceView类,
则FlutterActivity#onStart()最终会调用native方法FlutterJNI#nativeRunBundleAndSnapshotFromLibrary(
long nativeShellHolderId,
@NonNull String bundlePath,
@Nullable String entrypointFunctionName,
@Nullable String pathToEntrypointFunction,
@NonNull AssetManager manager,
@Nullable List entrypointArgs)
执行dart应用主入口函数,默认是main.dart文件的main函数
综上可以看出:
1.核心绘制逻辑是由FlutterView发起的(确切的说是FlutterView的成员变量renderSurface执行dart入口函数以及关联android应用端的Surface窗口,也就是绑定本地平台的窗口,android底层是ANativeWindow)
2.而FlutterActivity承接了组件生命周期方法回调
源码文件 main.dart
void main() {
runApp(const MyApp());
}
flutter dart framework 源码文件 widgets\binding.dart
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized()
..scheduleAttachRootWidget(app)
..scheduleWarmUpFrame();
}
void scheduleAttachRootWidget(Widget rootWidget) {
Timer.run(() {
attachRootWidget(rootWidget);
});
}
/// Takes a widget and attaches it to the [renderViewElement], creating it if
/// necessary.
///
/// This is called by [runApp] to configure the widget tree.
///
/// See also:
///
/// * [RenderObjectToWidgetAdapter.attachToRenderTree], which inflates a
/// widget and attaches it to the render tree.
void attachRootWidget(Widget rootWidget) {
final bool isBootstrapFrame = renderViewElement == null;
_readyToProduceFrames = true;
_renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
container: renderView,
debugShortDescription: '[root]',
child: rootWidget,
).attachToRenderTree(buildOwner!, renderViewElement as RenderObjectToWidgetElement<RenderBox>?);
if (isBootstrapFrame) {
SchedulerBinding.instance.ensureVisualUpdate();
}
}
在attachRootWidget函数中入参rootWidget为app开发者传递的根widget树,而成员变量renderView为根RenderObject树
/// Inflate this widget and actually set the resulting [RenderObject] as the
/// child of [container].
///
/// If `element` is null, this function will create a new element. Otherwise,
/// the given element will have an update scheduled to switch to this widget.
///
/// Used by [runApp] to bootstrap applications.
RenderObjectToWidgetElement<T> attachToRenderTree(BuildOwner owner, [ RenderObjectToWidgetElement<T>? element ]) {
if (element == null) {
owner.lockState(() {
element = createElement();
assert(element != null);
element!.assignOwner(owner);
});
owner.buildScope(element!, () {
element!.mount(null, null);
});
} else {
element._newWidget = this;
element.markNeedsBuild();
}
return element!;
}
而在attachToRenderTree函数中创建了关联的根Element树,至此初始化逻辑里完成了三棵树的创建与关联
flutter dart framework 源码文件 scheduler\binding.dart
void scheduleFrame() {
if (_hasScheduledFrame || !framesEnabled) {
return;
}
assert(() {
if (debugPrintScheduleFrameStacks) {
debugPrintStack(label: 'scheduleFrame() called. Current phase is $schedulerPhase.');
}
return true;
}());
ensureFrameCallbacksRegistered();
platformDispatcher.scheduleFrame();
_hasScheduledFrame = true;
}
flutter dart framework 源码文件 platform_dispatcher.dart
/// Requests that, at the next appropriate opportunity, the [onBeginFrame] and
/// [onDrawFrame] callbacks be invoked.
///
/// See also:
///
/// * [SchedulerBinding], the Flutter framework class which manages the
/// scheduling of frames.
void scheduleFrame() native 'PlatformConfiguration_scheduleFrame';
整个注册和回调执行流程,可以看到是从dart->native->java->native->dart的调用流程
总的来说就是:
dart (注册vysnc回调)
->native flutter engine层(c c++实现)
->java (flutter embedding库FlutterJNI.java、android系统Choreographer类)
->native flutter engine层(c c++实现)
->dart (vsync回调执行)
Flutter Android端只是三棵树(确切说是RenderObject树)渲染到Android Surface本地窗口
图层合成以及送显仍然交给SurfaceFlinger,并不是替代了SF,之前以为android平台Flutter完全替代了SF的理解是错误的
这里要提一下FlutterView为什么是FrameLayout子类,而不是直接用
FlutterSurfaceView、FlutterTextureView、FlutterImageView
因为只有非SurfaceView的普通view才能接受android系统ViewRootImpl派发的各种手势事件??这里用了一个AndroidTouchProcessor
public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) {
。。。
androidTouchProcessor =
new AndroidTouchProcessor(this.flutterEngine.getRenderer(), /*trackMotionEvents=*/ false);
。。。
}
FlutterVIew.java
public boolean onTouchEvent(@NonNull MotionEvent event) {
if (!isAttachedToFlutterEngine()) {
return super.onTouchEvent(event);
}
// TODO(abarth): This version check might not be effective in some
// versions of Android that statically compile code and will be upset
// at the lack of |requestUnbufferedDispatch|. Instead, we should factor
// version-dependent code into separate classes for each supported
// version and dispatch dynamically.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
requestUnbufferedDispatch(event);
}
return androidTouchProcessor.onTouchEvent(event);
}
AndroidTouchProcessor.java
/**
* Sends the given {@link MotionEvent} data to Flutter in a format that Flutter understands.
*
* @param event The motion event from the view.
* @param transformMatrix Applies to the view that originated the event. It's used to transform
* the gesture pointers into screen coordinates.
* @return True if the event was handled.
*/
public boolean onTouchEvent(@NonNull MotionEvent event, @NonNull Matrix transformMatrix) {
...
// Send the packet to Flutter.
renderer.dispatchPointerDataPacket(packet, packet.position());
...
return true;
}
FlutterRenderer.java
public void dispatchPointerDataPacket(@NonNull ByteBuffer buffer, int position) {
flutterJNI.dispatchPointerDataPacket(buffer, position);
}
FlutterJNI.java
@UiThread
public void dispatchPointerDataPacket(@NonNull ByteBuffer buffer, int position) {
ensureRunningOnMainThread();
ensureAttachedToNative();
nativeDispatchPointerDataPacket(nativeShellHolderId, buffer, position);
}
这里的关键函数nativeDispatchPointerDataPacket就是通过flutter engine间接把各种touch事件分发给了dart widget树
https://yanbober.blog.csdn.net/article/details/119086759