flutter-elinux启动流程解读

3 篇文章 2 订阅
3 篇文章 0 订阅

流程解说

1. 使用bundle资源路径构造flutter::DartProject对象
	1.1 bundle资源路径下需要 /data/flutter_assets,/data/icudtl.dat,/lib/libapp.so
		1.1.1 icudtl.dat 由FlutterTool提供,作为资源使用
		1.1.2 flutter_assets 由FlutterTool构建
		1.1.3 libapp.so 由FlutterTool构建,用于aot构建
	1.2 DartProject是官方的类,构造中仅保存三个文件路径

2. 创建flutter::FlutterViewController::ViewProperties对象,填充宽高,旋转角度,是否有光标等参数
3. 使用flutter::FlutterViewController::ViewProperties对象和flutter::DartProject对象构建FlutterWindow对象
	3.1 FlutterWindow对象应该就是自定义的

4. 调用FlutterWindow::OnCreate()方法启动引擎
	4.1 使用flutter::FlutterViewController::ViewProperties对象
	    和flutter::DartProject对象构造flutter::FlutterViewController对象
		4.1.1 构造中会使用flutter::DartProject对象构造flutter::FlutterEngine对象
			4.1.1.1 构造中会从DartProject中取出argc,argv,以及三资源的路径初始化FlutterDesktopEngineProperties
			4.1.1.2 构造中会使用FlutterDesktopEngineProperties构造FlutterProjectBundle对象
			4.1.1.3 构造中会创建一个TaskRunner对象(用于执行任务), 运行时会检测engine是否为空,
				不为空则会调用flutter API接口运行task(engine为FlutterEngine(添加符号是为了以后拓展),此时还未初始化)
  				task_runner_ = std::make_unique<TaskRunner>( 
      					std::this_thread::get_id(), embedder_api_.GetCurrentTime,
      					[this](const auto* task) {      
        				if (!engine_) {
          					ELINUX_LOG(ERROR)
              					<< "Cannot post an engine task when engine is not running.";
          					return;
        				}
        				if (embedder_api_.RunTask(engine_, task) != kSuccess) {
          					ELINUX_LOG(ERROR) << "Failed to post an engine task.";
        				}
      				});
			4.1.1.3 构造中会使用FlutterProjectBundle对象构造FlutterELinuxEngine对象
				4.1.1.3.1 构造中初始化FlutterEngineProcTable对象(内含Flutter操作API)
				4.1.1.3.2 构造中构造FlutterDesktopMessenger对象,并使用FlutterELinuxEngine初始化engine成员
				4.1.1.3.3 构造中创建FlutterDesktopPluginRegistrar对象,并使用FlutterELinuxEngine初始化engine成员
				4.1.1.3.4 构造中使用FlutterDesktopMessenger对象构造BinaryMessengerImpl对象
				4.1.1.3.5 构造中使用FlutterDesktopMessenger对象构造IncomingMessageDispatcherImpl对象
				4.1.1.3.6 构造中使用FlutterELinuxEngine对象构造FlutterELinuxTextureRegistrar对象
				4.1.1.3.7 构造中使用FlutterDesktopMessager对象,JsonMessageCodec单例json解码器构建BasicMessageChannel对象
					该消息通道的name为:"flutter/settings"
				4.1.1.3.8 构造中创建一个VsyncWaiter对象(通过该对象向flutter发送vsync事件)
			4.1.1.4 构造中会强制将FlutterELinuxEngine转化为FlutterDesktopEngine对象(实际就是个void*, 无法操作),
				并返回,目的是避免别人操作该对象,去掉类属性
			4.1.1.5 构造中会使用FlutterELinuxEngine对象中的FlutterDesktopMessenger对象构造BinaryMessengerImpl对象
		4.1.2 构造中会使用flutter::FlutterViewController::ViewProperties对象,
		      构造FlutterDesktopViewProperties(flutter-elinux自定义)对象
		4.1.3 构造中会使用FlutterDesktopViewProperties对象
		      和FlutterELinuxEngine对象调用FlutterDesktopViewControllerCreate
		      构造flutter::FlutterDesktopViewController对象
			4.1.3.1 使用FlutterDesktopViewProperties构造ELinuxWindowX11(父类为WindowBindingHandler)对象
				4.1.3.1.1 构造函数中将会创建Display对象(XOpenDisplay()过去Display)
			4.1.3.2 构造FlutterDesktopViewControllerState对象
			4.1.3.3 使用ELinuxWindowX11(父类为WindowBindingHandler)对象构造
			        FlutterELinuxView(父类为WindowBindingHandlerDelegate)对象,
				并将FlutterELinuxView(父类为WindowBindingHandlerDelegate)对象保存到
				FlutterDesktopViewControllerState对象中。
				4.1.3.3.1 构造中还将FlutterELinuxView设置到ELinuxWindowX11中,实现双向绑定
			4.1.3.4 调用FlutterDesktopViewController对象的CreateRenderSurface方法
				4.1.3.4.1 获取ELinuxWindowX11的尺寸
				4.1.3.4.2 调用ELinuxWindowX11的CreateRenderSurface方法(以下属于X11窗口机制,需要花事件理解)
					4.1.3.4.2.1 使用Display对象构造EnvromentEgl对象
						4.1.3.4.2.1.1 构造中使用EGLNativeDisplayType(理论上Dispaly应该是EGLNativeDisplayType的父类)
							      作为参数,调用eglGetDisplay获取EGLDisplay
						4.1.3.4.2.1.2 调用InitializeEgl(初始化egl)
					4.1.3.4.2.2 构造NativeWindowX11对象
						4.1.3.4.2.2.1 创建EGLNativeWindowType对象(XCreateWindow)
					4.1.3.4.2.3 使用EnvironmentElg对象构造SurfaceGL对象
					4.1.3.4.2.4 将SurfaceGL对象和NativeWindowX11对象绑定
			4.1.3.5 调用FlutterELinuxView::SetEngine将FlutterElinuxEngine设置到FlutterELinuxView对象中(双向绑定)
				4.1.3.5.1 获取FlutterELinuxEngine中的FlutterDesktopPluginRegistrar对象
					  构造flutter::PluginRegistrar对象
					4.1.3.5.1.1 使用FlutterDesktopPluginRegistrar中的FlutterDesktopMessenger
						    构造BinaryMessaengerImpl对象
					4.1.3.5.1.2 获取FlutterDesktopPluginRegistrar中的FlutterELinuxTextureRegistrar对象,
						    并强制转换为FlutterDesktopTextureRegistrar(不可操作)
					4.1.3.5.1.3 使用FlutterDesktopTextureRegistrar去构造TextureRegistrarImpl对象
				4.1.3.5.2 取出flutter::PluginRegistrar对象中的BinaryMessengerImpl对象
				4.1.3.5.3 使用BinaryMessengerImpl对象去构造flutter::KeyeventPlugin对象
					4.1.3.5.3.1 构造中会初始化键盘输入上下文(xkb_context)
				4.1.3.5.4 使用ELinuxWindowX11(父类为WindowBindingHandler)对象和BinaryMessengerImpl对象
					  去构造flutter::TextInputPlugin对象
					4.1.3.5.4.1 构造中会使用messenger和plugin去
						    构造flutter::MethodChannel<rapidjson::Document>对象
					4.1.3.5.4.2 设置MethodChannel的回调,回调中收到事件后
						    传给ELinuxWindowX11(::UpdateVirtualKeyboardStatus)
						    (事件从哪里来)
				4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
					  和BinaryMessengerImpl对象去构造flutter::PlatformPlugin对象
					  (事件从哪里来)
				4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
					  和BinaryMessengerImpl对象去构造flutter::MouseCursorPlugin对象
					  (事件从哪里来)
				4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
					  和BinaryMessengerImpl对象去构造flutter::LifecyclePlugin对象
					  (事件从哪里来)
				4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
					  和BinaryMessengerImpl对象去构造flutter::NavigationPlugin对象
					  (事件从哪里来)
				4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
					  和BinaryMessengerImpl对象去构造flutter::PlatformViewsPlugin对象
					  (事件从哪里来)
			4.1.3.6 调用FlutterELinuxEngine::RunWithEntrypoint运行引擎
				4.1.3.6.1 调用FlutterProjectBundle::HasValidPaths检查路径是否有效
				4.1.3.6.2 调用flutter_api的RunsAOTCompilesDartCode,应该是编译dart代码
				4.1.3.6.3 调用FlutterProjectBundle::LoadAotData函数获取FlutterEngineAOTData对象
					4.1.3.6.3.1 调用flutter_api的CreateAOTData构造FlutterEngineAOTData对象
					(其内部将libapp.so映射出来,之后加载过程中解析libapp.so二进制文件的头,段表,以及记录.dynstr和.dynsym段位置,
					 然后读取段_kDartVmSnapshotData起始地址,保存到vm_data中
					 然后读取段_kDartVmSnapshotInstructions起始地址,保存到vm_instrs中
					 然后读取段_kDartIsolateSnapshotData起始地址,保存到isolate_data中
					 然后读取段_kDartIsolateSnapshotInstructions起始地址,保存到isolate_instrs中)
				4.1.3.6.4 调用GetSwitchesFromEnvironment获取环境变量FLUTTER_ENGINE_SWITCH_${N}
					  然后将环境变量值加上前缀转换为--observatory-port=12345的形势
				4.1.3.6.5 新建FlutterTaskRunnerDescription结构体对象
					  .struct_size = sizeof(FlutterTaskRunnerDescription)
					  .user_data = TaskRunner对象
					  // 判断是否是当前线程
					  .runs_task_on_current_thread_callback = [](void* user_data) -> bool {
							return static_cast<TaskRunner*>(user_data)->RunsTasksOnCurrentThread();
					  };
					  // 抛出一个消息到主线程消息队列去执行
					  .post_task_callback = [](FlutterTask task,
								   uint64_t target_time_nanos,
								   void* user_data) -> void {
						static_cast<TaskRunner*>(user_data)->PostFlutterTask(task, target_time_nanos);
					  }; 
				4.1.3.6.6 新建FlutterCustomTaskRunners结构体对象
					  .struct_size = sizeof(FlutterCustomTaskRunners)
					  .platform_task_runner = FlutterTaskRunnerDescription对象
				4.1.3.6.7 新建FlutterProjectArgs结构体对象
					  .struct_size = sizeof(FlutterCustomTaskRunners)
					  .assets_path = flutter_assets路径
					  .icu_data_path = icudtl.dat路径
					  // 引擎启动参数
					  .command_line_argc = 前面由环境变量生成的参数的个数
					  .command_line_argv = 前面由环境变量生成的参数
					  // dart脚本启动参数
					  .dart_entrypoint_arg = 前面由环境变量生成的参数的个数
					  .dart_entrypoint_argv = 前面由环境变量生成的参数
					  // 监听并处理flutter消息
					  .platform_message_callback = [](const FlutterPlatformMessage* engine_message,
						void* user_data) -> void {
    						auto host = static_cast<FlutterELinuxEngine*>(user_data);
    						return host->HandlePlatformMessage(engine_message);
					  };
					  .custom_task_runners = FlutterCustomTaskRunners对象
					  .aot_data = FlutterEngineAOTData对象
					  // 指定dart脚本入口名, 为空默认main
					  .custom_dart_entrypoint = nullptr
					  // 日志消息处理
					  .log_message_callback = [](const char* tag, const char* message,void* user_data) {
					  };
				4.1.3.6.8 调用GetRendererConfig构造FlutterRenderConfig对象
					  // opengl引擎
					  config.type = kOpenGL
					  config.open_gl.struct_size = sizeof(config.open_gl)
					  config.open_gl.make_current = [](void* user_data) -> bool {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						if (!host->view()) {
							return false;
						}
						return host->view()->MakeCurrent();
					  };
					  config.open_gl.clear_current = [](void* user_data) -> bool {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						if (!host->view()) {
							return false;
						}
						return host->view()->ClearCurrent();
					  };
					  config.open_gl.present = [](void* user_data) -> bool {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						if (!host->view()) {
							return false;
						}
						return host->view()->Present();
					  }
					  config.open_gl.fbo_callback = [](void* user_data) -> uint32_t {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						if (!host->view()) {
							return false;
						}
						return host->view()->GetOnscreenFBO();
					  };
					  config.open_gl.gl_proc_resolver = [](void *user_data, 
										const char* name) -> void* {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						if (!host->view()) {
							return nullptr;
						}
						return host->view()->ProcResolver(name);
					  };
					  config.open_gl.make_resource_current = [](void* user_data) -> bool {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						if (!host->view()) {
							return false;
						}
						return host->view()->MakeResourceCurrent();
					  };
					  config.open_gl.gl_external_texture_frame_callback = [](void* user_data, 
						int64_t texture_id, size_t width, size_t height, FlutterOpenGLTextture *texture) {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						if (!host->texture_registrar()) {
							return false;
						}
						return host->texture_registrar()->PopulateTexture(texture_id, width, height, texture);
					  };
					  config.open_gl.surface_transformation = [](void* user_data) {
						auto host = static_cast<FlutterELinuxEngine*>(user_data);
						return host->view()->GetRootSurfaceTransformation();
					  };
				4.1.3.6.9 调用flutter_api->Run(),将FlutterEngine对象和FlutterRenderConfig对象对象作为参数传入
					4.1.3.6.9.1 FlutterEngine对象传入后,flutter引擎会调用FlutterEngine::messenger()接口获取消息传递对象BinaryMessengerImpl
						    (BinaryMessengerImpl内部持有FlutterDesktopMessenger,而FlutterDesktopMessenger内部持有FlutterELinuxEngine)
					4.1.3.6.9.2 flutter获取BinaryMessengerImpl后,会调用SetMeesageHandler接口,传递通道名以及消息传递对象BinaryMessageHandler过来
					4.1.3.6.9.3 然后会通过BinaryMessengerImpl深处的FlutterELinuxEngine对象的IncomingMessageDispatcher对象的SetMessageCallback接口
					4.1.3.6.9.4 将handler转换成FlutterDesktopMessageCallback对象保存起来,当flutter消息过来时触发回调,并处理消息
				4.1.3.6.10 调用SendSystemSettings进行系统设置
					4.1.3.6.9.1 获取所有支持的语言,并调用flutter_api的UpdateLocales,设置到引擎中
					4.1.3.6.9.2 创建json的配置,调用BasicMessageChannel::Send发送配置
					(发到flutter中,通道名为flutter/settings,
					路线:BasicMessageChannel->BinaryMessengerImpl->FlutterDesktopMessengerSend->FlutterELinuxEngine::SendPlatformMessage)
	4.2 调用FlutterWindow::Run()进入引擎的事件传递,分发,及处理
		4.2.1 FlutterViewController对象->FlutterView::DispatchEvent()->FlutterELinuxView::DispatchEvent()->ELinuxWindowX11::DisplayEvent()
		4.2.2 ELinuxWindowX11::DispatchEvent中将调用XNextEvent()获取用户输入
		4.2.3 根据事件的不同类型调用FlutterELinuxView::OnKey()等等接口
			4.2.4.1 首先调用KeyeventPlugin::OnKey()接口
				4.2.4.1.1 通过构造KeyeventPlugin时初始化的BasicMessageChannel对象发送消息json格式的event事件
				4.2.4.1.2 通过构造KeyeventPlugin时传入的BinaryMessengerImpl对象(flutter::PluginRegistrar构造内创建)去发送消息
				4.2.4.1.3 调用FlutterDesktopMessengerSend接口去发送消息(第一个参数时FlutterELinuxEngine对象中的FlutterDeskTopMessenger对象)
				4.2.4.1.4 通过FlutterDeskTopMessenger对象中的FlutterELinuxEngine对象的SendPlatformMessageResponse接口去发送
				4.2.4.1.5 通过flutter_api->SendPlatformMessage去发送生成的PlatformMessage
		(VSync是由窗口wayland发起的,x11没有发起vsync)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值