摘要
Flutter引擎启动源码详解。
Flutter技术架构概览
Flutter官方图分为三层,除了Framework、Engine、Embedder三层外,其实还有一层即我们在最上层编写的Dart代码。
- Framework(Dart):用Dart编写,封装整个Flutter架构的核心功能,包括Widget、动画、绘制、手势等功能,有Material(Android风格UI)和Cupertino(iOS风格)的UI界面, 可构建Widget控件以及实现UI布局;
- Engine(C/C++):用C++编写,实现了Flutter的核心库,包括Dart虚拟机、动画和图形、文字渲染、通信通道、事件通知、插件架构等。引擎渲染采用的是2D图形渲染库Skia,虚拟机采用的是面向对象语言Dart VM,并将它们托管到平台的中间层代码(Embedder);
- Embedder(Platform Specific):嵌入层,为Engine创建和管理线程,作用是把Engine的Task Runners(任务运行器)运行在嵌入层管理的线程上。
实现 Embedder API 的叫做 shell ,shell实现了平台相关的代码,比如跟屏幕键盘IME和系统应用生命周期事件的交互。不同平台有不同的shell,比如Android和iOS的shell。
Flutter引擎启动[基于Flutter 1.17.5 分析]
这里以Android为例,APP启动过程,会执行Application和Activity的onCreate()方法,FlutterApplication和FlutterActivity的onCreate()方法正是连接Native和Flutter的枢纽。
- FlutterApplication.java的onCreate过程主要完成初始化配置、加载引擎libflutter.so、注册JNI方法;
- FlutterActivity.java的onCreate过程,通过FlutterJNI的AttachJNI()方法来初始化引擎Engine、Dart虚拟机、Isolate、taskRunner等对象。再经过层层处理最终调用main.dart中main()方法,执行runApp(Widget app)来处理整个Dart业务代码。
1.FlutterApplication启动
在AndrodManifest.xml定义的FlutterApplication,Android应用在启动时候会执行FlutterApplication.onCreate(),然后再执行FlutterMain.startInitialization()方法,其主要工作:
- 确保该方法必须运行在主线程,否则抛出异常;
- 初始化FlutterLoader的相关配置信息flutter_assets、vm_snapshot_data、isolate_snapshot_data等,当metadata数据没有配置初始值时则采用默认值;
- 文件清理、提取资源(例如应用根目录下的所有assets资源等)加载到内存,这个过程都是在异步线程执行完成;
- 加载libflutter.so库,无论是System.loadLibrary(),还是System.load()最终都会调用到该加载库中的JNI_OnLoad() -> flutter/shell/platform/android/library_loader.cc:
- Android进程在由zygote fork过程中已创建了JavaVM,每一个进程对应一个JavaVM。在这里只是将当前进程的JavaVM实例保存在静态变量,再将当前线程和JavaVM建立关联,获取JNIEnv实例,每个线程对应一个JNIEnv实例 -> flutter/fml/platform/android/jni_util.cc
- 注册FlutterJNI的JNI方法,nativeInit()和nativeRecordStartTimestamp() -> flutter/shell/platform/android/flutter_main.cc
- 注册PlatformViewAndroid的一系列方法,完成Java和C++的一些方法互调 -> flutter/shell/platform/android/platform_view_android_jni.cc:
- 通过RegisterNatives()方法注册一些类的Native方法,用于Java调用C++的过程;
- 通过GetMethodID()方法记录了一些类的Java方法的jmethodID,用于C++调用Java的过程;
- 注册FlutterJNI的nativeOnVsync()用于Java调用C++,asyncWaitForVsync()用于C++调用Java -> flutter/shell/platform/android/vsync_waiter_android.cc;
- 最终通过engine_main_enter_ts变量记录FlutterApplication的启动耗时 -> flutter/shell/platform/android/flutter_main.cc
2.FlutterActivity启动
每一个FlutterActivity都会对应一个FlutterActivityAndFragmentDelegate代理类,FlutterActivity的工作全权委托给FlutterActivityAndFragmentDelegate类,包括onCreate(),onResume()等全部的生命周期回调方法。
2.1 FlutterActivity#onCreate
|
|
2.2 FlutterActivityAndFragmentDelegate#onAttach
- 当FlutterActivity复用时,Flutter Engine复用;否则初始化Flutter Engine[详见3],创建PlatformChannel、FlutterEnginePluginRegistry等对象
- 将Flutter Engine附加到FlutterActivity,以FlutterEnginePluginRegistry作为桥接媒介
- 调用io.flutter.plugins.GeneratedPluginRegistrant#registerWith方法,它是自动生成的类,与最上层我们写的Dart代码插件关联
2.3 FlutterActivityAndFragmentDelegate#onCreateView
- 创建FlutterView
- 给FlutterView添加第一帧绘制回调
- 创建FlutterSplashView,将FlutterView交给FlutterSplashView
将FlutterView挂载到Engine
2.4 FlutterActivityAndFragmentDelegate#onStart
|
|
2.4.0 doInitialFlutterViewRun
|
|
参数中的DartEntrypoint#dartEntrypointFunctionName代表主函数入口名,DartEntrypoint#pathToBundle代表对应库的路径,dartEntrypointFunctionName一般都等于”main”。
2.4.1 DartExecutor#executeDartEntrypoint
|
|
2.4.2 nativeRunBundleAndSnapshotFromLibrary
该native方法在
-> flutter/shell/platform/android/platform_view_android_jni.cc中注册,对应方法名为”RunBundleAndSnapshotFromLibrary”。
|
|
2.4.3 ANDROID_SHELL_HOLDER->Launch
-> flutter/shell/platform/android/android_shell_holder.cc
|
|
2.4.4 shell_->RunEngine
-> flutter/shell/common/shell.cc
|
|
2.4.5 weak_engine->Run
-> flutter/shell/common/engine.cc
|
|
2.4.6 PrepareAndLaunchIsolate
-> flutter/shell/common/engine.cc
|
|
从configuration中获取主函数入口,RunConfiguration有一个成员变量entrypoint_值等于“main”, 还有一个成员变量entrypointlibrary,这两个变量赋值的过程[见2.4.0]。
2.4.7 isolate->Run
-> flutter/runtime/dart_isolate.cc
|
|
2.4.8 InvokeMainEntrypoint
-> flutter/runtime/dart_isolate.cc
|
|
经过Dart虚拟机最终会调用的Dart层的_runMainZoned()方法,其中参数start_main_isolate_function等于_startIsolate。
2.4.9 _getStartMainIsolateFunction
未完待续
2.4.10 _runMainZoned
未完待续
3.FlutterEngine初始化
3.1 FlutterActivityAndFragmentDelegate#onAttach
|
|
3.2 FlutterActivityAndFragmentDelegate#setupFlutterEngine
|
|
3.3 FlutterEngine构造方法
|
|
3.3.1 flutterLoader.ensureInitializationComplete(context, dartVmArgs)
调用FlutterJNI#nativeInit,最终调用C++对应flutter_main.cc#FlutterMain::Init
3.3.2 this.attachToJni()
- 调用FlutterJNI#attachToNative->FlutterJNI#nativeAttach
(在加载flutter.so时注册该方法,见flutter/shell/platform/android/platform_view_android_jni.cc) - 调用C++对应platform_view_android_jni.cc#AttachJNI:为了在引擎层初始化AndroidShellHolder对象
3.4 AndroidShellHolder初始化
-> flutter/shell/platform/android/android_shell_holder.cc
|
|
该方法主要功能:
- 创建UI/GPU/IO三个线程,并为它们分别初始化MessageLoop、TaskRunner
- 创建TaskRunners对象 ->flutter/common/task_runners.cc
- on_create_platform_view
- on_create_rasterizer
- 创建Shell对象
3.5 ThreadHost初始化
-> flutter/shell/common/thread_host.cc
- 根据传递的参数,首次创建AndroidShellHolder实例的过程,会创建1.ui、1.gpu、1.io3个线程
- 每个线程Thread初始化过程 ->flutter/fml/thread.cc,都创建相应的MessageLoop ->flutter/fml/message_loop.cc、TaskRunner->flutter/fml/task_runner.cc对象,然后进入pollOnce轮询等待状态。
3.6 创建Shell
-> flutter/shell/common/shell.cc
|
|
3.6.1 PerformInitializationTasks()
->flutter/shell/common/shell.cc
默认情况只有ERROR级别的日志才会输出,除非在启动的时候带上参数verbose_logging,则会打印出INFO级别的日志。
3.6.2 DartVMRef::Create
-> flutter/runtime/dart_vm_lifecycle.cc
当该进程存在一个正在运行的虚拟机,获取其强引用,复用该虚拟机
123456789// If there is already a running VM in the process, grab a strong reference to// it.if (auto vm = gVM.lock()) {FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was ""already running. Ignoring arguments for current VM ""create call and reusing the old VM.";// There was already a running VM in the process,return DartVMRef{std::move(vm)};}如果没有则创建虚拟机
3.6.3 Shell::Create
-> flutter/shell/common/shell.cc
|
|
3.6.4 CreateShellOnPlatformThread
-> flutter/shell/common/shell.cc
|
|
3.6.5 创建Shell对象:Shell::Shell()
-> flutter/shell/common/shell.cc
创建Shell对象,成员变量taskrunners、settings以及vm赋初值
3.6.6 创建rasterizer对象
-> flutter/shell/common/rasterizer.cc
|
|
on_create_rasterizer方法等价于创建Rasterizer对象,在这个过程还会创建CompositorContext对象并赋值给compositorcontext。
3.6.7 创建platform_view:on_create_platform_view
-> flutter/shell/platform/android/platform_view_android.cc
|
|
on_create_platform_view方法的核心就是创建PlatformViewAndroid对象。
-> flutter/shell/platform/android/android_surface.cc
|
|
有三种不同的AndroidSurface。
3.6.8 创建vsync waiter:platform_view->CreateVSyncWaiter
-> flutter/shell/platform/android/platform_view_android.cc
|
|
-> flutter/shell/platform/android/vsync_waiter_android.cc
|
|
创建VsyncWaiterAndroid对象,也会初始化父类VsyncWaiter。
3.6.9 创建ShellIOManager
-> flutter/shell/common/shell_io_manager.cc
|
|
ShellIOManager的初始化过程,会创建GrContext和SkiaUnrefQueue对象。
3.6.10 创建Animator
-> flutter/shell/common/animator.cc
3.6.11 创建Engine
-> flutter/shell/common/engine.cc
创建RuntimeController对象。
-> flutter/runtime/runtime_controller.cc
|
|
3.6.11.1 创建Window:-> flutter/lib/ui/window/window.cc
3.6.11.2 创建RootIsolate:DartIsolate::CreateRootIsolate
-> flutter/runtime/dart_isolate.cc
|
|
3.6.12 shell->Setup
-> flutter/shell/common/shell.cc