【Flutter原理】Flutter App启动流程分析

}

我们先来看一下FlutterEngine的理解:

  1. 是一个独立的Flutter执行环境

  2. FlutterEngine 是一个容器,通过它可以在 Android 应用程序中运行 Dart 代码。

  3. FlutterEngine 中的 Dart 代码可以在后台执行,也可以使用附带的 FlutterRenderer 和 Dart 代码将 Dart 端 UI 效果渲染到屏幕上,渲染可以开始和停止,从而允许 FlutterEngine 从 UI 交互转移到仅进行数据处理,然后又返回到 UI 交互的能力。

  4. 可能同时存在多个FlutterEngine执行Dart代码,并且在单个Android应用程序中绘制UI。为了更好的内存性能特性,通过FlutterEngineGroup构造多个FlutterEngine,而不是直接通过FlutterEngine的构造函数。

  5. 使用 FlutterEngine 执行 Dart 或 Flutter 代码需要先通过 FlutterEngine 获取 DartExecutor 引用,然后调用 DartExecutor 的executeDartEntrypoint(DartExecutor.DartEntrypoint)执行 Dart 代码即可,同一个 FlutterEngine 实例中获取的 DartExecutor 的executeDartEntrypoint(DartExecutor.DartEntrypoint)方法只能被调用一次。

  6. 要开始将 Flutter 内容渲染到屏幕上,请使用 getRenderer() 获取 FlutterRenderer,然后附加一个 RenderSurface。 考虑使用 FlutterView 作为 RenderSurface。

  7. App 每个进程中创建第一个 FlutterEngine 实例的时候会加载 Flutter 引擎的原生库并启动 Dart VM(VM 存活生命周期跟随进程),随后同进程中其他的 FlutterEngines 将在同一个 VM 实例上运行,但在运行 DartExecutor 时将拥有自己的 Dart Isolate。每个 Isolate 都是一个独立的 Dart 环境,除非通过 Isolate 端口,否则无法相互通信。

  8. App 每个进程中创建第一个 FlutterEngine 实例的时候会加载 Flutter 引擎的原生库并启动 Dart VM(VM 存活生命周期跟随进程),随后同进程中其他的 FlutterEngine 将在同一个 VM 实例上运行,但在运行 DartExecutor 时将拥有自己的 Dart Isolate。每个 Isolate 都是一个独立的 Dart 环境,除非通过 Isolate 端口,否则无法相互通信。

最终整理对于一个多FlutterEngine的App来说,FlutterEngine,DartExecutor,Dart VM, Isloate关系如下:

在这里插入图片描述

接下来我们继续看FlutterEngine

public class FlutterEngine {

//Flutter C/C++与平台java层接口定义交互。Flutter 的引擎是用 C/C++ 构建的。 Android Flutter 嵌入负责协调 Android 操作系统事件和应用程序用户与 C/C++ 引擎的交互。

@NonNull private final FlutterJNI flutterJNI;

//表示 FlutterEngine 的渲染职责。

//FlutterRenderer 与提供的 RenderSurface 协同工作,将 Flutter 像素绘制到 Android 视图层次结构。

//FlutterRenderer 管理用于渲染的纹理,并通过 JNI 将一些 Java 调用转发到原生 Flutter 代码。 相应的 RenderSurface 提供此渲染器绘制的 Android Surface。

//io.flutter.embedding.android.FlutterSurfaceView 和 io.flutter.embedding.android.FlutterTextureView 是 RenderSurface 的实现

@NonNull private final FlutterRenderer renderer;

//Dart执行器。

@NonNull private final DartExecutor dartExecutor;

//用来管理安卓组件和Flutter plugins插件。

@NonNull private final FlutterEngineConnectionRegistry pluginRegistry;

//localization的安卓端实现插件。

@NonNull private final LocalizationPlugin localizationPlugin;

//一堆系统通道。负责与系统底层通信

@NonNull private final AccessibilityChannel accessibilityChannel;

@NonNull private final DeferredComponentChannel deferredComponentChannel;

@NonNull private final KeyEventChannel keyEventChannel;

@NonNull private final LifecycleChannel lifecycleChannel;

@NonNull private final LocalizationChannel localizationChannel;

@NonNull private final MouseCursorChannel mouseCursorChannel;

@NonNull private final NavigationChannel navigationChannel;

@NonNull private final RestorationChannel restorationChannel;

@NonNull private final PlatformChannel platformChannel;

@NonNull private final SettingsChannel settingsChannel;

@NonNull private final SystemChannel systemChannel;

@NonNull private final TextInputChannel textInputChannel;

// Platform Views.

// 管理平台视图。每个 io.flutter.app.FlutterPluginRegistry 都有一个平台视图控制器。 一个平台视图控制器最多可以附加到一个 Flutter 视图

@NonNull private final PlatformViewsController platformViewsController;

// Engine Lifecycle.

// 引擎声明周期监听

@NonNull private final Set engineLifecycleListeners = new HashSet<>();

//…

//全参数的构造函数,各种构造最终都走进这里

public FlutterEngine(

@NonNull Context context,

@Nullable FlutterLoader flutterLoader,

@NonNull FlutterJNI flutterJNI,

@NonNull PlatformViewsController platformViewsController,

@Nullable String[] dartVmArgs,

boolean automaticallyRegisterPlugins,

boolean waitForRestorationData) {

//…

//创建一个DartExecutor并将flutterJNI和安卓平台的assetManager实例传递进去。

this.dartExecutor = new DartExecutor(flutterJNI, assetManager);

this.dartExecutor.onAttachedToJNI();

//…

//各种channel实例化

accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI);

deferredComponentChannel = new DeferredComponentChannel(dartExecutor);

keyEventChannel = new KeyEventChannel(dartExecutor);

lifecycleChannel = new LifecycleChannel(dartExecutor);

localizationChannel = new LocalizationChannel(dartExecutor);

mouseCursorChannel = new MouseCursorChannel(dartExecutor);

navigationChannel = new NavigationChannel(dartExecutor);

platformChannel = new PlatformChannel(dartExecutor);

restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);

settingsChannel = new SettingsChannel(dartExecutor);

systemChannel = new SystemChannel(dartExecutor);

textInputChannel = new TextInputChannel(dartExecutor);

//…

//插件实例化。

this.localizationPlugin = new LocalizationPlugin(context, localizationChannel);

this.flutterJNI = flutterJNI;

if (flutterLoader == null) {

flutterLoader = FlutterInjector.instance().flutterLoader();

}

//…

// 引擎与四大组件的桥梁

this.pluginRegistry =

new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, flutterLoader);

//默认就是自动注册plugins的,可以通过清单文件配置变更等。

if (automaticallyRegisterPlugins && flutterLoader.automaticallyRegisterPlugins()) {

registerPlugins();

}

}

//…

//注册flutter项目根目录下pubspec.yaml中依赖的所有flutter plugins。

//Flutter tool会生成一个GeneratedPluginRegistrant的类。

private void registerPlugins() {

try {

Class<?> generatedPluginRegistrant = Class.forName(“io.flutter.plugins.GeneratedPluginRegistrant”);

Method registrationMethod = generatedPluginRegistrant.getDeclaredMethod(“registerWith”, FlutterEngine.class);

registrationMethod.invoke(null, this);

} catch (Exception e) {

Log.w(TAG, “Tried to automatically register plugins with FlutterEngine (”

  • this + “) but could not find and invoke the GeneratedPluginRegistrant.”);

}

}

//…省略一堆属性成员的get方法

}

总结下Flutter主要作用:

  1. FlutterEngineConnectionRegistry:创建组件与四大引擎生命周期的桥梁,方便插件根据各个组件的生命周期处理

  2. registerPlugins:通过反射注册自定义插件

  3. 各种Channel的初始化,建立引擎与平台系统之间的桥梁

  4. DartExecutor:Dart执行环境创建,onAttachedToJNI之后,DartExecutor将开始处理与Dart上下文之间的双向通行,BinaryMessenger(向Dart发送消息),PlatformMessageHandler,它接受来自Dart的消息

  5. FlutterRenderer:渲染环境的创建

到此FlutterEngine基本创建完成,内部细节不做详解。下面再来分析下createFlutterView

createFlutterView

createFlutterView走到了FlutterActivityAndFragmentDelegate的onCreateView方法

@NonNull

View onCreateView(

LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

Log.v(TAG, “Creating FlutterView.”);

ensureAlive();

if (host.getRenderMode() == RenderMode.surface) {

FlutterSurfaceView flutterSurfaceView =

new FlutterSurfaceView(

host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent);

// 允许自定义flutterSurfaceView

host.onFlutterSurfaceViewCreated(flutterSurfaceView);

// 创建拥有 FlutterSurfaceView 的 FlutterView。

flutterView = new FlutterView(host.getActivity(), flutterSurfaceView);

} else {

FlutterTextureView flutterTextureView = new FlutterTextureView(host.getActivity());

// 允许自定义flutterTextureView

host.onFlutterTextureViewCreated(flutterTextureView);

// 创建拥有 FlutterTextureView 的 FlutterView。

flutterView = new FlutterView(host.getActivity(), flutterTextureView);

}

// 添加侦听器以在 Flutter 呈现其第一帧时收到通知。

flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener);

flutterSplashView = new FlutterSplashView(host.getContext());

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

flutterSplashView.setId(View.generateViewId());

} else {

flutterSplashView.setId(486947586);

}

flutterSplashView.displayFlutterViewWithSplash(flutterView, host.provideSplashScreen());

Log.v(TAG, “Attaching FlutterEngine to FlutterView.”);

flutterView.attachToFlutterEngine(flutterEngine);

return flutterSplashView;

}

该方法主要完成四个任务:

  1. 在 View 层次结构中创建一个新的 FlutterView

  2. 添加一个 FlutterUiDisplayListener

  3. 将 FlutterEngine 附加到新的 FlutterView

  4. flutterSplashView(主要作用是在 FlutterView render 渲染出来之前显示一个SplashScreen),类似于过度图

我们在简单看下FlutterView,FlutterView是一个Android 原生的控件,继承自FrameLayout,它之所以显示的是Flutter UI,完全是依赖于FlutterSurfaceView和FlutterTextureView,而FlutterSurfaceView和FlutterTextureView这两个View的绘制内容又是来自于FlutterEngine提供。

FlutterView源码分析,我们后面再来单独讲…
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

【附】相关架构及资料

往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

ps://img2.imgtp.com/2024/03/13/H4lCoPEF.jpg" />

【附】相关架构及资料

[外链图片转存中…(img-hRWVEvAv-1712684469914)]

[外链图片转存中…(img-hrDKmRmr-1712684469914)]

往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值