日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入分析 Flutter 初始化流程

發布時間:2025/3/19 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入分析 Flutter 初始化流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在調研 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 environmentjAssetManager, // asset managerstd::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 的初始化流程就就簡單的分析了一遍。大致可以總結成三個部分

  • 初始化 FlutterMain
  • 初始化 FlutterView,開始加載 bundle
  • 初始化Flutter Bundle,這里獲取了 Flutter 的入口方法、Flutter 的 library, 以及對 Flutter 入口方法的調用。
  • 初始化的邏輯比較復雜,對后續一些初始化相關的性能優化應該也會有不小的啟發。FlutterMain 中對資源的處理和寫入本地的邏輯也給 Android 端研究 Flutter 動態化提供了基礎。

    很多 bundle 加載和后續初始化的邏輯也還沒有完全弄清楚和深入研究。有興趣的朋友可以一起研究,共同探討。

    總結

    以上是生活随笔為你收集整理的深入分析 Flutter 初始化流程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。