深入解析 Flutter 初始化流程

简介: 在调研 Flutter 动态化方案的时候,需要了解 Flutter 加载 dart 产物的流程,于是梳理了一遍 FLutter 的初始化流程flutter的源码下载地址在 github 上可以找到,具体地址: gith...

在调研 Flutter 动态化方案的时候,需要了解 Flutter 加载 dart 产物的流程,于是梳理了一遍 FLutter 的初始化流程

flutter的源码下载地址在 github 上可以找到,具体地址: github-flutter/engine

FLutterMain的初始化

先从 Android 的入口开始看

在 FlutterAppliation 的 onCreate 中调用了

FlutterMain.startInitialization(this);

跟进去我们会看到调用了 startInitialization 方法,最后会顺序调用这几个方法

initConfig(applicationContext);
initAot(applicationContext);
initResources(applicationContext);

我们查看 initResources 方法如图

这里我们可以看到实际加载了assets里面的flutter资源。并且会把资源 copy 到本地的�路径。这里不做深究。 FlutterMan 的初始化基本包括了

  • 初始化配置
  • 初始化 AOT 编译
  • 初始化资源

3 个部分

继续看 � Flutter 的 View 的初始化:

FLutterView的初始化

以 FlutterActivity 为例,在 onCreate 中会调用到 FlutterActivityDelegate 的对应方法,最终调用 FlutterView 的 runFromBundle 方法

public void runFromBundle(FlutterRunArguments args) {
    this.assertAttached();
    this.preRun();
    this.mNativeView.runFromBundle(args);
    this.postRun();
}

跟踪这段代码,会调用 FlutterNativeView 的 nativeRunBundleAndSnapshotFromLibrary 方法。

这里会继续进行 � jni 层的调用,�查看 platform_view_android_jni.cc

{
    .name = "nativeRunBundleAndSnapshotFromLibrary",
    .signature = "(J[Ljava/lang/String; Ljava/lang/String;"
    "Ljava/lang/String;Landroid/content/res/AssetManager;)V",
    .fnPtr = reinterpret_cast<void*>          (shell::RunBundleAndSnapshotFromLibrary),
},

查看 RunBundleAndSnapshotFromLibrary ,这里删除了一些我们不关心的逻辑

static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
                                            jobject jcaller,
                                            jlong shell_holder,
                                            jobjectArray jbundlepaths,
                                            jstring jEntrypoint,
                                            jstring jLibraryUrl,
                                            jobject jAssetManager) {
    auto asset_manager = std::make_shared<blink::AssetManager>();      
       for (const auto& bundlepath :
       fml::jni::StringArrayToVector(env, jbundlepaths)) {
    const auto file_ext_index = bundlepath.rfind(".");
    if (bundlepath.substr(file_ext_index) == ".zip") {
      asset_manager->PushBack(
          std::make_unique<blink::ZipAssetStore>(bundlepath));
    } else {
      asset_manager->PushBack(
          std::make_unique<blink::DirectoryAssetBundle>(fml::OpenDirectory(
              bundlepath.c_str(), false, fml::FilePermission::kRead)));
      const auto last_slash_index = bundlepath.rfind("/", bundlepath.size());
      if (last_slash_index != std::string::npos) {
        auto apk_asset_dir = bundlepath.substr(
            last_slash_index + 1, bundlepath.size() - last_slash_index);

        asset_manager->PushBack(std::make_unique<blink::APKAssetProvider>(
            env,                       // jni environment
            jAssetManager,             // asset manager
            std::move(apk_asset_dir))  // apk asset dir
        );
      }
    }
  }      
  auto isolate_configuration = CreateIsolateConfiguration(*asset_manager);    
  RunConfiguration config(std::move(isolate_configuration),
                          std::move(asset_manager));  
    ANDROID_SHELL_HOLDER->Launch(std::move(config));

首先会对资源路径进行处理 会�分为 zip 包或者文件夹进行分别处理。最终会调用常量 ANDROID_SHELL_HOLDER的 Launch 函数.

最终走到 engine 的 Run 函数。

这里有 2 个函数比较重要,先是 IsolateConfiguration::PrepareIsolate , 然后是 RunFromLibrary 或者 Run 函数

跟到 PrepareAndLaunchIsolate 函数,查看源码

bool IsolateConfiguration::PrepareIsolate(blink::DartIsolate& isolate) {
  if (isolate.GetPhase() != blink::DartIsolate::Phase::LibrariesSetup) {
    FML_DLOG(ERROR)
        << "Isolate was in incorrect phase to be prepared for running.";
    return false;
  }

  return DoPrepareIsolate(isolate);
}

而有 DoPrepareIsolate 函数的类 Configuration 类有3个

  • AppSnapshotIsolateConfiguration
  • KernelIsolateConfiguration
  • KernelListIsolateConfiguration

他们分别会调用 DartIsolate 的

  • PrepareForRunningFromPrecompiledCode
  • PrepareForRunningFromKernel

这2个方法的一个,可以�看到这里的 prepare 操作分成了 预先加载的代码 和 从内核获取 2种

至于 RunFromLibrary 函数和 Run 函数

我们能看到�他们最终都会调用 dart:isolate 和 _startMainIsolate 的逻辑:

Dart_Handle isolate_lib = Dart_LookupLibrary(tonic::ToDart("dart:isolate"));
if (tonic::LogIfError(Dart_Invoke(
          isolate_lib, tonic::ToDart("_startMainIsolate"),
          sizeof(isolate_args) / sizeof(isolate_args[0]), isolate_args))) {
    return false;
  }

这里说明我们正在执行调用 Dart 的入口方法。而 Run 和 RunFromLibrary 的区别,则是如果我们传入了 entrypoint 参数去进行 Flutter 的 bundle 初始化的时候,则会去加载我们制定的 library。

小结

到这里, Flutter 的初始化流程就就简单的分析了一遍。大致可以总结成三个部分

  1. 初始化 FlutterMain
  2. 初始化 FlutterView,开始加载 bundle
  3. 初始化Flutter Bundle,这里获取了 Flutter 的入口方法、Flutter 的 library, 以及对 Flutter 入口方法的调用。

初始化的逻辑比较复杂,对后续一些初始化相关的性能优化应该也会有不小的启发。 FlutterMain 中对资源的处理和写入本地的逻辑也给 Android 端研究 Flutter 动态化提供了基础。

有需要Android进阶全面系统视频资料的可以加入Android进阶交流群;701740775。免费获取 加群请备注csdn领取进阶资料

相关文章
|
2天前
|
存储 Rust 监控
EtherCAT主站IgH解析(一)--主站初始化、状态机与EtherCAT报文
本文介绍了IgH EtherCAT Master整体运行原理
8 0
EtherCAT主站IgH解析(一)--主站初始化、状态机与EtherCAT报文
|
2天前
|
算法 Linux 调度
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
7 1
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
|
2天前
|
Linux 调度 数据库
|
2天前
|
Linux API 调度
xenomai内核解析-xenomai实时线程创建流程
本文介绍了linux硬实时操作系统xenomai pthread_creta()接口的底层实现原理,解释了如何在双内核间创建和调度一个xenomai任务。本文是基于源代码的分析,提供了详细的流程和注释,同时给出了结论部分,方便读者快速了解核心内容。
6 0
xenomai内核解析-xenomai实时线程创建流程
|
4天前
|
供应链 监控 安全
全面剖析:新页ERP系统不为人知的一面,以及系统的工作流程解析!
全面剖析:新页ERP系统不为人知的一面,以及系统的工作流程解析!
|
12天前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
【4月更文挑战第30天】Dart是Google为Flutter框架打造的高效编程语言,具有易学性、接口、混入、抽象类等特性。本文概述了Dart的基础语法,包括静态类型(如int、String)、控制流程(条件、循环)、函数、面向对象(类与对象)和异常处理。此外,还介绍了库导入与模块使用,帮助开发者快速入门Flutter开发。通过学习Dart,开发者能创建高性能的应用。
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
|
12天前
|
Dart 测试技术 UED
Dart 和 Flutter 错误处理指南 | 最佳实践全解析
深入探索 Dart 和 Flutter 中的错误处理技术,从编译时错误到运行时异常,带你学习如何优雅地处理应用程序中的各种意外情况。了解最佳实践,让你的应用程序稳如磐石,用户体验持续优化!
Dart 和 Flutter 错误处理指南 | 最佳实践全解析
|
12天前
|
缓存 Java 开发者
10个点介绍SpringBoot3工作流程与核心组件源码解析
Spring Boot 是Java开发中100%会使用到的框架,开发者不仅要熟练使用,对其中的核心源码也要了解,正所谓知其然知其所以然,V 哥建议小伙伴们在学习的过程中,一定要去研读一下源码,这有助于你在开发中游刃有余。欢迎一起交流学习心得,一起成长。
|
16天前
|
开发框架 Dart API
Flutter引擎工作原理:深入解析FlutterEngine
【4月更文挑战第26天】FlutterEngine是Flutter应用的关键,负责Dart代码转换为原生代码,管理应用生命周期、渲染和事件处理。它初始化Flutter运行时环境,加载并编译Dart代码,创建渲染树,处理事件并实现跨平台兼容。通过理解其工作原理,开发者能更好地掌握Flutter应用内部机制并优化开发。随着Flutter生态系统发展,FlutterEngine将持续提供强大支持。
|
16天前
|
Dart Java Android开发
Flutter插件开发:开发与使用的技术解析
【4月更文挑战第26天】本文详细介绍了Flutter插件开发,包括创建插件项目、编写原生代码(Android和iOS)、注册与使用插件。通过Flutter命令行工具生成插件,使用MethodChannel进行Dart与原生平台的通信。示例展示了如何获取设备信息并展示在Flutter应用中。文章还提到插件测试与发布,强调了兼容性与性能的重要性,指出Flutter插件是扩展应用功能的关键。

推荐镜像

更多