發表日期:2019-01 文章編輯:小燈 瀏覽次數:3039
在調研 Flutter 動態化方案的時候,需要了解 Flutter 加載 dart 產物的流程,于是梳理了一遍 FLutter 的初始化流程
flutter的源碼下載地址在 github 上可以找到,具體地址: github-flutter/engine
先從 Android 的入口開始看
在 FlutterAppliation
的 onCreate
中調用了
FlutterMain.startInitialization(this);
跟進去我們會看到調用了 startInitialization
方法,最后會順序調用這幾個方法
initConfig(applicationContext); initAot(applicationContext); initResources(applicationContext);
我們查看 initResources
方法如圖
這里我們可以看到實際加載了assets里面的flutter資源。并且會把資源 copy 到本地的?路徑。這里不做深究。 FlutterMan
的初始化基本包括了
3 個部分
繼續看 ? Flutter
的 View
的初始化:
以 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個
他們分別會調用 DartIsolate
的
這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
中對資源的處理和寫入本地的邏輯也給 Android 端研究 Flutter 動態化提供了基礎。
日期:2018-10 瀏覽次數:7253
日期:2018-12 瀏覽次數:4328
日期:2018-07 瀏覽次數:4876
日期:2018-12 瀏覽次數:4174
日期:2018-09 瀏覽次數:5502
日期:2018-12 瀏覽次數:9922
日期:2018-11 瀏覽次數:4804
日期:2018-07 瀏覽次數:4578
日期:2018-05 瀏覽次數:4859
日期:2018-12 瀏覽次數:4324
日期:2018-10 瀏覽次數:5139
日期:2018-12 瀏覽次數:6212
日期:2018-11 瀏覽次數:4464
日期:2018-08 瀏覽次數:4592
日期:2018-11 瀏覽次數:12630
日期:2018-09 瀏覽次數:5579
日期:2018-12 瀏覽次數:4832
日期:2018-10 瀏覽次數:4188
日期:2018-11 瀏覽次數:4528
日期:2018-12 瀏覽次數:6063
日期:2018-06 瀏覽次數:4007
日期:2018-08 瀏覽次數:5436
日期:2018-10 瀏覽次數:4457
日期:2018-12 瀏覽次數:4525
日期:2018-07 瀏覽次數:4362
日期:2018-12 瀏覽次數:4500
日期:2018-06 瀏覽次數:4383
日期:2018-11 瀏覽次數:4375
日期:2018-12 瀏覽次數:4249
日期:2018-12 瀏覽次數:5283
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.