Dart VM是用C++编写的,Flutter中只有一个相对较小的部分是用iOS编写的,称为shell。对于iOS,您可以在Flutter/engine的此目录中找到文件。我自己还在学习/浏览Flutter内部。
回答您的问题,Dart VM在所有隔离区之间共享,并在您的应用程序进程中运行。在一个进程中只能运行1个Dart VM,这是Dart VM的设计(而不是构造它,您要求一个,它会给您相同的一个,也就是单例模式)。一个普通的flutter应用程序是一个单独的隔离区,但您可以在一个iOS进程/应用程序中运行多个Flutter Engines/ Dart入口点(main
方法)。Dart VM管理隔离区,因此它不在一个线程中运行。从阅读mrale.ph/dartvm,内部使用线程池和管理操作系统线程,因此绝对不限于一个线程。
操作系统线程和隔离区之间的关系有些模糊,并且高度依赖于VM嵌入到应用程序中的方式。
VM内部使用线程池(dart::ThreadPool)管理操作系统线程,并且代码的结构是围绕着dart::ThreadPool::Task的概念而非操作系统线程的概念进行构建的。
更多调查
阅读https://mrale.ph/dartvm/,您可以克隆Flutter/engine project并查找FLUTTER_RUNTIME_MODE
字符串,以了解在调试、分析、发布和JIT发布之间的Flutter逻辑变化。
#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
#if !OS_IOS && !OS_MACOSX
PushBackAll(&args, kDartWriteProtectCodeArgs,
fml::size(kDartWriteProtectCodeArgs));
#else
const bool tracing_result = EnableTracingIfNecessary(settings_);
FML_CHECK(tracing_result)
<< "Tracing not enabled before attempting to run JIT mode VM.";
#if TARGET_CPU_ARM
PushBackAll(&args, kDartDisableIntegerDivisionArgs,
fml::size(kDartDisableIntegerDivisionArgs));
#endif
#endif
#endif
或者,在 FlutterPluginAppLifeCycleDelegate.mm
中:
您可以看到,如果应用程序在调试模式下运行,则当应用程序进入前台时,后台任务 _debugBackgroundTask
将被取消。当设备屏幕锁定时,这个 _debugBackgroundTask
是在应用程序进入后台时创建的,以保持 Flutter 会话的活动状态。更多信息 在此处。
- (void)handleWillEnterForeground:(NSNotification*)notification {
UIApplication* application = [UIApplication sharedApplication];
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
if (_debugBackgroundTask != UIBackgroundTaskInvalid) {
[application endBackgroundTask:_debugBackgroundTask];
_debugBackgroundTask = UIBackgroundTaskInvalid;
}
#endif
for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in _delegates) {
if (!delegate) {
continue;
}
if ([delegate respondsToSelector:@selector(applicationWillEnterForeground:)]) {
[delegate applicationWillEnterForeground:application];
}
}
}