欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

Flutter在Android平台上启动时,Native层做了什么?,

来源: 开发者 投稿于  被查看 43809 次 评论:161

Flutter在Android平台上启动时,Native层做了什么?,


前言

接上回 Flutter——在Android平台上的启动流程浅析,

我们来看看穿插在其中的native层都做了什么。

由于代码较多,我会将说明以注释的形式写在代码里,并删除非必要代码

FlutterLoader

在flutterLoader中的这个startInitialization()方法中:

  1. public void startInitialization(@NonNull Context applicationContext, @NonNull FlutterLoader.Settings settings) { 
  2.       if (this.settings == null) { 
  3.           if (Looper.myLooper() != Looper.getMainLooper()) { 
  4.               throw new IllegalStateException("startInitialization must be called on the main thread"); 
  5.           } else { 
  6.               .... 
  7.               Callable<FlutterLoader.InitResult> initTask = new Callable<FlutterLoader.InitResult>() { 
  8.                   public FlutterLoader.InitResult call() { 
  9.                       .... 
  10.                       ///这里是在子线程执行的 
  11.                       System.loadLibrary("flutter"); 
  12.                       .... 
  13.  
  14.                       return new FlutterLoader.InitResult(PathUtils.getFilesDir(appContext), PathUtils.getCacheDirectory(appContext), PathUtils.getDataDirectory(appContext)); 
  15.                   } 
  16.               }; 
  17.               this.initResultFuture = Executors.newSingleThreadExecutor().submit(initTask); 
  18.           } 
  19.       } 
  20.   } 

System.loadLibrary("flutter");并不是简单地加载flutter框架代码,它最终会进入native中的JNI_OnLoad方法:

  1. // This is called by the VM when the shared library is first loaded. 
  2. JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { 
  3.   // 初始化 JVM (只是将虚拟机进行一个保存) 
  4.   // 之后关联到当前线程上 
  5.   fml::jni::InitJavaVM(vm); 
  6.  
  7.   JNIEnv* env = fml::jni::AttachCurrentThread(); 
  8.   bool result = false; 
  9.  
  10.   // 注册 FlutterMain. 
  11.   result = flutter::FlutterMain::Register(env); 
  12.   FML_CHECK(result); 
  13.  
  14.   // 注册 PlatformView 
  15.   // 这里会注册大量的方法,使c++和java可以互相调用 
  16.   result = flutter::PlatformViewAndroid::Register(env); 
  17.   FML_CHECK(result); 
  18.  
  19.   // 注册 VSyncWaiter. 
  20.   // 这里将java的VSyncWaiter类中的方法与 
  21.   // native中的VsyncWaiterAndroid的映射,便可以互相调用 
  22.   result = flutter::VsyncWaiterAndroid::Register(env); 
  23.   FML_CHECK(result); 
  24.  
  25.   return JNI_VERSION_1_4; 
  1. tip:PlatformViewAndroid路径为:engine/shell/platform/android 

有兴趣的话,可以看看

整体来看,这里主要是保存了jvm,同时对c++和java的方法进行了映射以便双方可以互相调用。

至此FlutterApplication中所拉起的native代码就简单概括完了,我们接着FlutterActivity中所调用native代码。

FlutterActivity & onCreate

这里需要提一下,目前你搜索FlutterActivity这个类,会发现有两个:

  1. android/FlutterActivity   这个是最新的 
  2. app/FlutterActivity    已过期 

经过一系列调用,具体见这篇文章: Flutter——在Android平台上的启动流程浅析,

会初始化flutterEngine,构造函数如下:

  1. //很长,但是其中初始化的东西还是比较有用的 
  2. //所以我觉得有必要贴一下 
  3.  
  4.   /** Fully configurable {@code FlutterEngine} constructor. */ 
  5.   public FlutterEngine( 
  6.       @NonNull Context context, 
  7.       @NonNull FlutterLoader flutterLoader, 
  8.       @NonNull FlutterJNI flutterJNI, 
  9.       @NonNull PlatformViewsController platformViewsController, 
  10.       @Nullable String[] dartVmArgs, 
  11.       boolean automaticallyRegisterPlugins, 
  12.       boolean waitForRestorationData) { 
  13.     this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets()); 
  14.     this.dartExecutor.onAttachedToJNI(); 
  15.  
  16.     accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI); 
  17.     keyEventChannel = new KeyEventChannel(dartExecutor); 
  18.     lifecycleChannel = new LifecycleChannel(dartExecutor); 
  19.     localizationChannel = new LocalizationChannel(dartExecutor); 
  20.     mouseCursorChannel = new MouseCursorChannel(dartExecutor); 
  21.     navigationChannel = new NavigationChannel(dartExecutor); 
  22.     platformChannel = new PlatformChannel(dartExecutor); 
  23.     restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData); 
  24.     settingsChannel = new SettingsChannel(dartExecutor); 
  25.     systemChannel = new SystemChannel(dartExecutor); 
  26.     textInputChannel = new TextInputChannel(dartExecutor); 
  27.  
  28.     this.localizationPlugin = new LocalizationPlugin(context, localizationChannel); 
  29.  
  30.     this.flutterJNI = flutterJNI; 
  31.     flutterLoader.startInitialization(context.getApplicationContext()); 
  32.     ///注意这里 
  33.     flutterLoader.ensureInitializationComplete(context, dartVmArgs); 
  34.  
  35.     flutterJNI.addEngineLifecycleListener(engineLifecycleListener); 
  36.     flutterJNI.setPlatformViewsController(platformViewsController); 
  37.     flutterJNI.setLocalizationPlugin(localizationPlugin); 
  38.     attachToJni(); 
  39.  
  40.     // TODO(mattcarroll): FlutterRenderer is temporally coupled to attach(). Remove that coupling if 
  41.     // possible. 
  42.     this.renderer = new FlutterRenderer(flutterJNI); 
  43.  
  44.     this.platformViewsController = platformViewsController; 
  45.     this.platformViewsController.onAttachedToJNI(); 
  46.  
  47.     this.pluginRegistry = 
  48.         new FlutterEnginePluginRegistry(context.getApplicationContext(), this, flutterLoader); 
  49.  
  50.     if (automaticallyRegisterPlugins) { 
  51.       registerPlugins(); 
  52.     } 
  53.   } 

整个构造函数会初始化大量channel,同时进行一些native方法注册,其中:

  1. flutterLoader.ensureInitializationComplete(context, dartVmArgs); 

会转到native,详细代码如下:

  1. ///此方法会阻塞,直到native 系统工作执行完毕 
  2.  
  3.   public void ensureInitializationComplete( 
  4.       @NonNull Context applicationContext, @Nullable String[] args) { 
  5.     if (initialized) { 
  6.       return; 
  7.     } 
  8.     if (Looper.myLooper() != Looper.getMainLooper()) { 
  9.       throw new IllegalStateException( 
  10.           "ensureInitializationComplete must be called on the main thread"); 
  11.     } 
  12.     if (settings == null) { 
  13.       throw new IllegalStateException( 
  14.           "ensureInitializationComplete must be called after startInitialization"); 
  15.     } 
  16.      
  17.     ///收集各种文件路径 
  18.      
  19.     try { 
  20.       InitResult result = initResultFuture.get(); 
  21.  
  22.       List<String> shellArgs = new ArrayList<>(); 
  23.       shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat"); 
  24.  
  25.       ApplicationInfo applicationInfo = getApplicationInfo(applicationContext); 
  26.       shellArgs.add( 
  27.           "--icu-native-lib-path=" 
  28.               + applicationInfo.nativeLibraryDir 
  29.               + File.separator 
  30.               + DEFAULT_LIBRARY); 
  31.       if (args != null) { 
  32.         Collections.addAll(shellArgs, args); 
  33.       } 
  34.  
  35.       String kernelPath = null; 
  36.       if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) { 
  37.         String snapshotAssetPath = result.dataDirPath + File.separator + flutterAssetsDir; 
  38.         kernelPath = snapshotAssetPath + File.separator + DEFAULT_KERNEL_BLOB; 
  39.         shellArgs.add("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath); 
  40.         shellArgs.add("--" + VM_SNAPSHOT_DATA_KEY + "=" + vmSnapshotData); 
  41.         shellArgs.add("--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + isolateSnapshotData); 
  42.       } else { 
  43.         shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + aotSharedLibraryName); 
  44.  
  45.         // Most devices can load the AOT shared library based on the library name 
  46.         // with no directory path.  Provide a fully qualified path to the library 
  47.         // as a workaround for devices where that fails. 
  48.         shellArgs.add( 
  49.             "--" 
  50.                 + AOT_SHARED_LIBRARY_NAME 
  51.                 + "=" 
  52.                 + applicationInfo.nativeLibraryDir 
  53.                 + File.separator 
  54.                 + aotSharedLibraryName); 
  55.       } 
  56.  
  57.       shellArgs.add("--cache-dir-path=" + result.engineCachesPath); 
  58.       if (settings.getLogTag() != null) { 
  59.         shellArgs.add("--log-tag=" + settings.getLogTag()); 
  60.       } 
  61.  
  62.       long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis; 
  63.  
  64.       // TODO(cyanlaz): Remove this when dynamic thread merging is done. 
  65.       // https://github.com/flutter/flutter/issues/59930 
  66.       Bundle bundle = applicationInfo.metaData; 
  67.       if (bundle != null) { 
  68.         boolean use_embedded_view = bundle.getBoolean("io.flutter.embedded_views_preview"); 
  69.         if (use_embedded_view) { 
  70.           shellArgs.add("--use-embedded-view"); 
  71.         } 
  72.       } 
  73.        
  74.      /// 拉起native 
  75.       
  76.       FlutterJNI.nativeInit( 
  77.           applicationContext, 
  78.           shellArgs.toArray(new String[0]), 
  79.           kernelPath, 
  80.           result.appStoragePath, 
  81.           result.engineCachesPath, 
  82.           initTimeMillis); 
  83.  
  84.       initialized = true; 
  85.     } catch (Exception e) { 
  86.       Log.e(TAG, "Flutter initialization failed.", e); 
  87.       throw new RuntimeException(e); 
  88.     } 
  89.   } 

这里会将相关的信息通过FlutterJNI.nativeInit,即:

  1. ///native 方法 
  2.   public static native void nativeInit( 
  3.       @NonNull Context context, 
  4.       @NonNull String[] args, 
  5.       @Nullable String bundlePath, 
  6.       @NonNull String appStoragePath, 
  7.       @NonNull String engineCachesPath, 
  8.       long initTimeMillis); 

传递到native层,还记得上部分我们注册的flutterMain方法吗?

FlutterMain::Register

  1. bool FlutterMain::Register(JNIEnv* env) { 
  2.   static const JNINativeMethod methods[] = { 
  3.       { 
  4.         ///看这里 name是方法名的意思 
  5.           .name = "nativeInit", 
  6.           .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/" 
  7.                        "lang/String;Ljava/lang/String;Ljava/lang/String;J)V", 
  8.                         
  9.                        ///方法&Init的地址被保存在了fnPtr上 
  10.           .fnPtr = reinterpret_cast<void*>(&Init), 
  11.       }, 
  12.       { 
  13.           .name = "nativePrefetchDefaultFontManager", 
  14.           .signature = "()V", 
  15.           .fnPtr = reinterpret_cast<void*>(&PrefetchDefaultFontManager), 
  16.       }, 
  17.   }; 
  18.  
  19.   jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI"); 
  20.  
  21.   if (clazz == nullptr) { 
  22.     return false; 
  23.   } 
  24.  
  25.   return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0; 

通过指针.fnPtr = reinterpret_cast(&Init),便会拉起它的FlutterMain::Init方法。

  1. void FlutterMain::Init(JNIEnv* env, 
  2.                        jclass clazz, 
  3.                        jobject context, 
  4.                        jobjectArray jargs, 
  5.                        jstring kernelPath, 
  6.                        jstring appStoragePath, 
  7.                        jstring engineCachesPath, 
  8.                        jlong initTimeMillis) { 
  9.   std::vector<std::string> args; 
  10.   ///tag 
  11.   args.push_back("flutter"); 
  12.   ///将上面我们收集的那些路径信息保存到 args中 
  13.   ///以‘j’ 表示java传过来的。 
  14.   for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) { 
  15.     args.push_back(std::move(arg)); 
  16.   } 
  17.   auto command_line = fml::CommandLineFromIterators(args.begin(), args.end()); 
  18.  
  19.   auto settings = SettingsFromCommandLine(command_line); 
  20.   ///engine启动时间 
  21.   int64_t init_time_micros = initTimeMillis * 1000; 
  22.   settings.engine_start_timestamp = 
  23.       std::chrono::microseconds(Dart_TimelineGetMicros() - init_time_micros); 
  24.  
  25.   // Restore the callback cache. 
  26.   // TODO(chinmaygarde): Route all cache file access through FML and remove this 
  27.   // setter. 
  28.   flutter::DartCallbackCache::SetCachePath( 
  29.       fml::jni::JavaStringToString(env, appStoragePath)); 
  30.  ///初始化缓存路径 
  31.   fml::paths::InitializeAndroidCachesPath( 
  32.       fml::jni::JavaStringToString(env, engineCachesPath)); 
  33.   ///加载缓存 
  34.   flutter::DartCallbackCache::LoadCacheFromDisk(); 
  35.  
  36.   if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) { 
  37.     // Check to see if the appropriate kernel files are present and configure 
  38.     // settings accordingly. 
  39.     auto application_kernel_path = 
  40.         fml::jni::JavaStringToString(env, kernelPath); 
  41.  
  42.     if (fml::IsFile(application_kernel_path)) { 
  43.       settings.application_kernel_asset = application_kernel_path; 
  44.     } 
  45.   } 
  46.  
  47.   settings.task_observer_add = [](intptr_t key, fml::closure callback) { 
  48.     fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback)); 
  49.   }; 
  50.  
  51.   settings.task_observer_remove = [](intptr_t key) { 
  52.     fml::MessageLoop::GetCurrent().RemoveTaskObserver(key); 
  53.   }; 
  54.  
  55. #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG 
  56.   // There are no ownership concerns here as all mappings are owned by the 
  57.   // embedder and not the engine. 
  58.   auto make_mapping_callback = [](const uint8_t* mapping, size_t size) { 
  59.     return [mapping, size]() { 
  60.       return std::make_unique<fml::NonOwnedMapping>(mapping, size); 
  61.     }; 
  62.   }; 
  63.  
  64.   settings.dart_library_sources_kernel = 
  65.       make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize); 
  66. #endif  // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG 
  67.  
  68.   // Not thread safe. Will be removed when FlutterMain is refactored to no 
  69.   // longer be a singleton. 
  70.   g_flutter_main.reset(new FlutterMain(std::move(settings))); 
  71.  
  72.   g_flutter_main->SetupObservatoryUriCallback(env); 

以上主要是对java传过来的数据进行保存,至此由flutterLoader.ensureInitializationComplete所引起的native执行完毕,在其后面会执行attachToJni()。

FlutterActivity& attachToJni()

attachToJni()最终会调用flutterJNI.attachToNative(false):

  1. ///这步完成后,android便可以与engine通信了 
  2.   @UiThread 
  3.   public void attachToNative(boolean isBackgroundView) { 
  4.     ensureRunningOnMainThread(); 
  5.     ensureNotAttachedToNative(); 
  6.     nativePlatformViewId = nativeAttach(this, isBackgroundView); 
  7.   } 
  8.  
  9.   private native long nativeAttach(@NonNull FlutterJNI flutterJNI, boolean isBackgroundView);  

此方法会调用native的:

  1. static jlong AttachJNI(JNIEnv* env, 
  2.                        jclass clazz, 
  3.                        jobject flutterJNI, 
  4.                        jboolean is_background_view) { 
  5.   fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI); 
  6.   std::shared_ptr<PlatformViewAndroidJNI> jni_facade = 
  7.       std::make_shared<PlatformViewAndroidJNIImpl>(java_object); 
  8.       ///主要就是初始化一个 shell holder 
  9.   auto shell_holder = std::make_unique<AndroidShellHolder>( 
  10.       FlutterMain::Get().GetSettings(), jni_facade, is_background_view); 
  11.   if (shell_holder->IsValid()) { 
  12.     return reinterpret_cast<jlong>(shell_holder.release()); 
  13.   } else { 
  14.     return 0; 
  15.   } 

我们来看一下AndroidShellHolder.cc的实现

AndroidShellHolder & gpu/ui/io线程的创建

它有一个100多行的构造函数:

  1. AndroidShellHolder::AndroidShellHolder( 
  2.     flutter::Settings settings, 
  3.     std::shared_ptr<PlatformViewAndroidJNI> jni_facade, 
  4.     bool is_background_view) 
  5.     : settings_(std::move(settings)), jni_facade_(jni_facade) { 
  6.   static size_t shell_count = 1; 
  7.   auto thread_label = std::to_string(shell_count++); 
  8.  
  9.   FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) == 
  10.             0); 
  11.   ///这里我们传递的是false 
  12.   if (is_background_view) { 
  13.     thread_host_ = {thread_label, ThreadHost::Type::UI}; 
  14.   } else { 
  15.   /// 会创建三个线程 分别是 UI\GPU\IO 
  16.     thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU | 
  17.                                       ThreadHost::Type::IO}; 
  18.   } 
  19.  
  20.   // Detach from JNI when the UI and raster threads exit. 
  21.   // UI和raster线程退出时,与JNI分离 
  22.   // raster就是gpu线程,它将我们的绘制指令转为gpu指令 
  23.   auto jni_exit_task([key = thread_destruct_key_]() { 
  24.     FML_CHECK(pthread_setspecific(key, reinterpret_cast<void*>(1)) == 0); 
  25.   }); 
  26.   thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task); 
  27.   if (!is_background_view) { 
  28.     thread_host_.raster_thread->GetTaskRunner()->PostTask(jni_exit_task); 
  29.   } 
  30.  
  31.   fml::WeakPtr<PlatformViewAndroid> weak_platform_view; 
  32.   Shell::CreateCallback<PlatformView> on_create_platform_view = 
  33.       [is_background_view, &jni_facade, &weak_platform_view](Shell& shell) { 
  34.         std::unique_ptr<PlatformViewAndroid> platform_view_android; 
  35.         if (is_background_view) { 
  36.           ...走下面 
  37.         } else { 
  38.         ///初始化了一个PlatformViewAndroid 
  39.           platform_view_android = std::make_unique<PlatformViewAndroid>( 
  40.               shell,                   // delegate 
  41.               shell.GetTaskRunners(),  // task runners 
  42.               jni_facade,              // JNI interop 
  43.               shell.GetSettings() 
  44.                   .enable_software_rendering  // use software rendering 
  45.           ); 
  46.         } 
  47.         weak_platform_view = platform_view_android->GetWeakPtr(); 
  48.         shell.OnDisplayUpdates(DisplayUpdateType::kStartup, 
  49.                                {Display(jni_facade->GetDisplayRefreshRate())}); 
  50.         return platform_view_android; 
  51.       }; 
  52.  
  53.   Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) { 
  54.     return std::make_unique<Rasterizer>(shell); 
  55.   }; 
  56.  
  57.   // The current thread will be used as the platform thread. Ensure that the 
  58.   // message loop is initialized. 
  59.   // 初始化native的 message loop 
  60.   // gpu/ui/io它们也有各自的 msg loop 
  61.   fml::MessageLoop::EnsureInitializedForCurrentThread(); 
  62.   ///初始化对应线程的task runner 
  63.   /// 这样我们便可以向指定线程post 任务 
  64.   fml::RefPtr<fml::TaskRunner> gpu_runner; 
  65.   fml::RefPtr<fml::TaskRunner> ui_runner; 
  66.   fml::RefPtr<fml::TaskRunner> io_runner; 
  67.   fml::RefPtr<fml::TaskRunner> platform_runner = 
  68.       fml::MessageLoop::GetCurrent().GetTaskRunner(); 
  69.   if (is_background_view) { 
  70.     auto single_task_runner = thread_host_.ui_thread->GetTaskRunner(); 
  71.     gpu_runner = single_task_runner; 
  72.     ui_runner = single_task_runner; 
  73.     io_runner = single_task_runner; 
  74.   } else { 
  75.     gpu_runner = thread_host_.raster_thread->GetTaskRunner(); 
  76.     ui_runner = thread_host_.ui_thread->GetTaskRunner(); 
  77.     io_runner = thread_host_.io_thread->GetTaskRunner(); 
  78.   } 
  79.    
  80.   flutter::TaskRunners task_runners(thread_label,     // label 
  81.                                     platform_runner,  // platform 
  82.                                     gpu_runner,       // raster 
  83.                                     ui_runner,        // ui 
  84.                                     io_runner         // io 
  85.   ); 
  86.   ///提高ui 和 gpu线程等级 
  87.   ///线程值 越小 等级越高 
  88.   task_runners.GetRasterTaskRunner()->PostTask([]() { 
  89.     // Android describes -8 as "most important display threads, for 
  90.     // compositing the screen and retrieving input events". Conservatively 
  91.     // set the raster thread to slightly lower priority than it. 
  92.     if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) { 
  93.       // Defensive fallback. Depending on the OEM, it may not be possible 
  94.       // to set priority to -5. 
  95.       if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) { 
  96.         FML_LOG(ERROR) << "Failed to set GPU task runner priority"; 
  97.       } 
  98.     } 
  99.   }); 
  100.   task_runners.GetUITaskRunner()->PostTask([]() { 
  101.     if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) { 
  102.       FML_LOG(ERROR) << "Failed to set UI task runner priority"; 
  103.     } 
  104.   }); 
  105.     ///创建shell 
  106.   shell_ = 
  107.       Shell::Create(task_runners,              // task runners 
  108.                     GetDefaultPlatformData(),  // window data 
  109.                     settings_,                 // settings 
  110.                     on_create_platform_view,   // platform view create callback 
  111.                     on_create_rasterizer       // rasterizer create callback 
  112.       ); 
  113.  
  114.   platform_view_ = weak_platform_view; 
  115.   FML_DCHECK(platform_view_); 
  116.   is_valid_ = shell_ != nullptr; 

Shell

我们接着看一下 shell_的创建:

  1. std::unique_ptr<Shell> Shell::Create( 
  2.     TaskRunners task_runners, 
  3.     const PlatformData platform_data, 
  4.     Settings settings, 
  5.     Shell::CreateCallback<PlatformView> on_create_platform_view, 
  6.     Shell::CreateCallback<Rasterizer> on_create_rasterizer) { 
  7.   PerformInitializationTasks(settings); 
  8.   PersistentCache::SetCacheSkSL(settings.cache_sksl); 
  9.  
  10.   TRACE_EVENT0("flutter", "Shell::Create"); 
  11.   ///创建虚拟机 
  12.   auto vm = DartVMRef::Create(settings); 
  13.   FML_CHECK(vm) << "Must be able to initialize the VM."; 
  14.  
  15.   auto vm_data = vm->GetVMData(); 
  16.  
  17.   return Shell::Create(std::move(task_runners),        // 
  18.                        std::move(platform_data),       // 
  19.                        std::move(settings),            // 
  20.                        vm_data->GetIsolateSnapshot(),  // isolate snapshot 
  21.                        on_create_platform_view,        // 
  22.                        on_create_rasterizer,           // 
  23.                        std::move(vm)                   // 
  24.   ); 

DartVMRef::Create

  1. DartVMRef DartVMRef::Create(Settings settings, 
  2.                             fml::RefPtr<DartSnapshot> vm_snapshot, 
  3.                             fml::RefPtr<DartSnapshot> isolate_snapshot) { 
  4.   std::scoped_lock lifecycle_lock(gVMMutex); 
  5.  
  6.   ...删除一些代码 
  7.  
  8.   //这里对已有的虚拟机进行复用 
  9.   if (auto vm = gVM.lock()) { 
  10.     FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was " 
  11.                          "already running. Ignoring arguments for current VM " 
  12.                          "create call and reusing the old VM."; 
  13.     // There was already a running VM in the process, 
  14.     return DartVMRef{std::move(vm)}; 
  15.   } 
  16.  
  17.   ...删除一些代码 
  18.  
  19.   //如果没有,就重新创建一个虚拟机 
  20.   auto isolate_name_server = std::make_shared<IsolateNameServer>(); 
  21.   auto vm = DartVM::Create(std::move(settings),          // 
  22.                            std::move(vm_snapshot),       // 
  23.                            std::move(isolate_snapshot),  // 
  24.                            isolate_name_server           // 
  25.   ); 
  26.  
  27.   ...删除一些代码 
  28.  
  29.   return DartVMRef{std::move(vm)}; 

我们继续看shell的创建,最终会调用CreateShellOnPlatformThread。

Shell & CreateShellOnPlatformThread

  1. std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread( 
  2.     DartVMRef vm, 
  3.     TaskRunners task_runners, 
  4.     const PlatformData platform_data, 
  5.     Settings settings, 
  6.     fml::RefPtr<const DartSnapshot> isolate_snapshot, 
  7.     const Shell::CreateCallback<PlatformView>& on_create_platform_view, 
  8.     const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) { 
  9.      
  10.   ... 
  11.     ///创建对象 
  12.   auto shell = 
  13.       std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings)); 
  14.  
  15.   // 创建rasterizer :工作在gpu线程 
  16.   // 这里要说一下,gpu线程还是在cpu上的,只是这个线程叫gpu 而已 
  17.   std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise; 
  18.   auto rasterizer_future = rasterizer_promise.get_future(); 
  19.   std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise; 
  20.   auto snapshot_delegate_future = snapshot_delegate_promise.get_future(); 
  21.   fml::TaskRunner::RunNowOrPostTask( 
  22.       task_runners.GetRasterTaskRunner(), [&rasterizer_promise,  // 
  23.                                            &snapshot_delegate_promise, 
  24.                                            on_create_rasterizer,  // 
  25.                                            shell = shell.get()    // 
  26.   ]() { 
  27.         TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem"); 
  28.         std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell)); 
  29.         snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate()); 
  30.         rasterizer_promise.set_value(std::move(rasterizer)); 
  31.       }); 
  32.  
  33.   // 在当前线程(platform thread)创建platform view. 
  34.   auto platform_view = on_create_platform_view(*shell.get()); 
  35.   if (!platform_view || !platform_view->GetWeakPtr()) { 
  36.     return nullptr; 
  37.   } 
  38.  
  39.   // Ask the platform view for the vsync waiter. This will be used by the engine 
  40.   // to create the animator. 
  41.   auto vsync_waiter = platform_view->CreateVSyncWaiter(); 
  42.   if (!vsync_waiter) { 
  43.     return nullptr; 
  44.   } 
  45.  
  46.   ...删除部分代码... 
  47.    
  48.   ///通过向 io线程post task 来创建 io manager 
  49.   fml::TaskRunner::RunNowOrPostTask( 
  50.       io_task_runner, 
  51.       [&io_manager_promise,                                               // 
  52.        &weak_io_manager_promise,                                          // 
  53.        &unref_queue_promise,                                              // 
  54.        platform_view = platform_view->GetWeakPtr(),                       // 
  55.        io_task_runner,                                                    // 
  56.        is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch()  // 
  57.   ]() { 
  58.         TRACE_EVENT0("flutter", "ShellSetupIOSubsystem"); 
  59.         auto io_manager = std::make_unique<ShellIOManager>( 
  60.             platform_view.getUnsafe()->CreateResourceContext(), 
  61.             is_backgrounded_sync_switch, io_task_runner); 
  62.         weak_io_manager_promise.set_value(io_manager->GetWeakPtr()); 
  63.         unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue()); 
  64.         io_manager_promise.set_value(std::move(io_manager)); 
  65.       }); 
  66.  
  67.   // Send dispatcher_maker to the engine constructor because shell won't have 
  68.   // platform_view set until Shell::Setup is called later. 
  69.   auto dispatcher_maker = platform_view->GetDispatcherMaker(); 
  70.  
  71.   // 在ui线程创建engine 
  72.   // 这里的engine指针被跨线程使用 
  73.   std::promise<std::unique_ptr<Engine>> engine_promise; 
  74.   auto engine_future = engine_promise.get_future(); 
  75.   fml::TaskRunner::RunNowOrPostTask( 
  76.       shell->GetTaskRunners().GetUITaskRunner(), 
  77.       fml::MakeCopyable([&engine_promise,                                 // 
  78.                          shell = shell.get(),                             // 
  79.                          &dispatcher_maker,                               // 
  80.                          &platform_data,                                  // 
  81.                          isolate_snapshot = std::move(isolate_snapshot),  // 
  82.                          vsync_waiter = std::move(vsync_waiter),          // 
  83.                          &weak_io_manager_future,                         // 
  84.                          &snapshot_delegate_future,                       // 
  85.                          &unref_queue_future                              // 
  86.   ]() mutable { 
  87.         TRACE_EVENT0("flutter", "ShellSetupUISubsystem"); 
  88.         const auto& task_runners = shell->GetTaskRunners(); 
  89.  
  90.         // 创建animator(ui线程) 
  91.         auto animator = std::make_unique<Animator>(*shell, task_runners, 
  92.                                                    std::move(vsync_waiter)); 
  93.  
  94.         engine_promise.set_value(std::make_unique<Engine>( 
  95.             *shell,                         // 
  96.             dispatcher_maker,               // 
  97.             *shell->GetDartVM(),            // 
  98.             std::move(isolate_snapshot),    // 
  99.             task_runners,                   // 
  100.             platform_data,                  // 
  101.             shell->GetSettings(),           // 
  102.             std::move(animator),            // 
  103.             weak_io_manager_future.get(),   // 
  104.             unref_queue_future.get(),       // 
  105.             snapshot_delegate_future.get()  // 
  106.             )); 
  107.       })); 
  108.  
  109.   if (!shell->Setup(std::move(platform_view),  // 
  110.                     engine_future.get(),       // 
  111.                     rasterizer_future.get(),   // 
  112.                     io_manager_future.get())   // 
  113.   ) { 
  114.     return nullptr; 
  115.   } 
  116.  
  117.   return shell; 

由于代码太长,这里再汇总一下:

shell初始化之后,还有分别在io/ui/gpu/platform线程创建以下对象:

  • rasterizer 在gpu线程工作,负责将绘制指令转为gpu指令
  • platform view 在当前线程(platform thread)
  • engine 和 animator 在ui线程工作

flutter最终会通过animator向platformView 申请VSync信号

接下来我们再看一下上面代码中对engine的初始化。

Engine

代码相对较少,但是连接的东西非常多:

  1. Engine::Engine(Delegate& delegate, 
  2.                const PointerDataDispatcherMaker& dispatcher_maker, 
  3.                DartVM& vm, 
  4.                fml::RefPtr<const DartSnapshot> isolate_snapshot, 
  5.                TaskRunners task_runners, 
  6.                const PlatformData platform_data, 
  7.                Settings settings, 
  8.                std::unique_ptr<Animator> animator, 
  9.                fml::WeakPtr<IOManager> io_manager, 
  10.                fml::RefPtr<SkiaUnrefQueue> unref_queue, 
  11.                fml::WeakPtr<SnapshotDelegate> snapshot_delegate) 
  12.     : Engine(delegate, 
  13.              dispatcher_maker, 
  14.              vm.GetConcurrentWorkerTaskRunner(), 
  15.              task_runners, 
  16.              settings, 
  17.              std::move(animator), 
  18.              io_manager, 
  19.              nullptr) { 
  20.   runtime_controller_ = std::make_unique<RuntimeController>( 
  21.       *this,                                 // runtime delegate 
  22.       &vm,                                   // VM 
  23.       std::move(isolate_snapshot),           // isolate snapshot 
  24.       task_runners_,                         // task runners 
  25.       std::move(snapshot_delegate),          // snapshot delegate 
  26.       GetWeakPtr(),                          // hint freed delegate 
  27.       std::move(io_manager),                 // io manager 
  28.       std::move(unref_queue),                // Skia unref queue 
  29.       image_decoder_.GetWeakPtr(),           // image decoder 
  30.       settings_.advisory_script_uri,         // advisory script uri 
  31.       settings_.advisory_script_entrypoint,  // advisory script entrypoint 
  32.       settings_.idle_notification_callback,  // idle notification callback 
  33.       platform_data,                         // platform data 
  34.       settings_.isolate_create_callback,     // isolate create callback 
  35.       settings_.isolate_shutdown_callback,   // isolate shutdown callback 
  36.       settings_.persistent_isolate_data      // persistent isolate data 
  37.   ); 

就是创建了一个runtime_controller_ ,你可以将runtime controller 看做native、platform和flutter的一个纽带。

小结

经过上面一系列的代码,可能有点晕,概括来讲Flutter Activity在注册flutterMain过程中会创建初始化shell,而在这个初始化的过程中,我们分别会创建三个线程,算上当前线程的话,就是4个:

  • platform 线程(当前线程)
  • ui 线程
  • gpu 线程
  • io 线程

并初始化一系列重要对象。

好的,我们再回到主线,onCreate()已经过了,下面我们可以看一下onStart()生命周期:

FlutterActivity & onStart

此方法会调用 delegate.onStart(); 并最终调用FlutterJNI的native方法:

  1. private native void nativeRunBundleAndSnapshotFromLibrary( 
  2.     long nativePlatformViewId, 
  3.     @NonNull String bundlePath, 
  4.     @Nullable String entrypointFunctionName, 
  5.     @Nullable String pathToEntrypointFunction, 
  6.     @NonNull AssetManager manager); 

从这里开始,其终点就是执行dart的代码。

Launch

接着我们看一下native方法:

(位置在platform_view_android_jni_impl.cc)

  1. static void RunBundleAndSnapshotFromLibrary(JNIEnv* env, 
  2.                                             jobject jcaller, 
  3.                                             jlong shell_holder, 
  4.                                             jstring jBundlePath, 
  5.                                             jstring jEntrypoint, 
  6.                                             jstring jLibraryUrl, 
  7.                                             jobject jAssetManager) { 
  8.   ...删除部分代码 
  9.   ///这里主要是根据参数,生成一个config 并用于启动 
  10.   /// 我们的 默认启动入口 'main()'就在这个config里 
  11.  
  12.   ANDROID_SHELL_HOLDER->Launch(std::move(config)); 

我们接着看Launch(std::move(config));方法:

  1. void AndroidShellHolder::Launch(RunConfiguration config) { 
  2.   if (!IsValid()) { 
  3.     return; 
  4.   } 
  5.  
  6.   shell_->RunEngine(std::move(config)); 

又调用了 run engine 方法:

  1. void Shell::RunEngine( 
  2.     RunConfiguration run_configuration, 
  3.     const std::function<void(Engine::RunStatus)>& result_callback) { 
  4.   ...删除一些代码 
  5.  
  6. ///向 ui线程post了一个任务 
  7.   fml::TaskRunner::RunNowOrPostTask( 
  8.       task_runners_.GetUITaskRunner(), 
  9.       fml::MakeCopyable( 
  10.           [run_configuration = std::move(run_configuration), 
  11.            weak_engine = weak_engine_, result]() mutable { 
  12.             if (!weak_engine) { 
  13.               FML_LOG(ERROR) 
  14.                   << "Could not launch engine with configuration - no engine."; 
  15.               result(Engine::RunStatus::Failure); 
  16.               return; 
  17.             } 
  18.             ///调用engine的run方法 
  19.             auto run_result = weak_engine->Run(std::move(run_configuration)); 
  20.             if (run_result == flutter::Engine::RunStatus::Failure) { 
  21.               FML_LOG(ERROR) << "Could not launch engine with configuration."; 
  22.             } 
  23.             result(run_result); 
  24.           })); 

Engin.run()

  1. Engine::RunStatus Engine::Run(RunConfiguration configuration) { 
  2.   if (!configuration.IsValid()) { 
  3.     FML_LOG(ERROR) << "Engine run configuration was invalid."; 
  4.     return RunStatus::Failure; 
  5.   } 
  6.  ///获取要执行的 dart代码入口点 
  7.  ///这里就是 main方法 from mian.dart 
  8.   last_entry_point_ = configuration.GetEntrypoint(); 
  9.   last_entry_point_library_ = configuration.GetEntrypointLibrary(); 
  10.  
  11.   .... 
  12.    
  13.   ///调用了LaunchRootIsolate方法 
  14.   if (!runtime_controller_->LaunchRootIsolate( 
  15.           settings_,                                 // 
  16.           configuration.GetEntrypoint(),             // 
  17.           configuration.GetEntrypointLibrary(),      // 
  18.           configuration.TakeIsolateConfiguration())  // 
  19.   ) { 
  20.     return RunStatus::Failure; 
  21.   } 
  22.  
  23.   ...删除部分代码 
  24.  
  25.   return Engine::RunStatus::Success; 

LaunchRootIsolate

  1. bool RuntimeController::LaunchRootIsolate( 
  2.     const Settings& settings, 
  3.     std::optional<std::string> dart_entrypoint, 
  4.     std::optional<std::string> dart_entrypoint_library, 
  5.     std::unique_ptr<IsolateConfiguration> isolate_configuration) { 
  6.   if (root_isolate_.lock()) { 
  7.     FML_LOG(ERROR) << "Root isolate was already running."; 
  8.     return false; 
  9.   } 
  10.  ///创建一个 ‘运行’的 root isolate 
  11.   auto strong_root_isolate = 
  12.       DartIsolate::CreateRunningRootIsolate( 
  13.           settings,                                       // 配置 
  14.           isolate_snapshot_,                              // 快照 
  15.           task_runners_,                                  //  
  16.           std::make_unique<PlatformConfiguration>(this),  // 平台配置 
  17.           snapshot_delegate_,                             // 
  18.           hint_freed_delegate_,                           // 
  19.           io_manager_,                                    // io管理运行在Io线程 
  20.           unref_queue_,                                   //  
  21.           image_decoder_,                                 // 图片解码 
  22.           advisory_script_uri_,                           // 
  23.           advisory_script_entrypoint_,                    // 
  24.           DartIsolate::Flags{},                           // 
  25.           isolate_create_callback_,                       // 
  26.           isolate_shutdown_callback_,                     // 
  27.           dart_entrypoint,                                // 入口 方法(main.dart) 
  28.           dart_entrypoint_library,                        // 入口库 
  29.           std::move(isolate_configuration)                // 
  30.           ) 
  31.           .lock(); 
  32.  
  33.   ...删除部分代码 
  34.  
  35.   return true; 

我们看一下DartIsolate的CreateRunningRootIsolate方法

DartIsolate::CreateRunningRootIsolate

  1. std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate( 
  2.     const Settings& settings, 
  3.     fml::RefPtr<const DartSnapshot> isolate_snapshot, 
  4.     TaskRunners task_runners, 
  5.     std::unique_ptr<PlatformConfiguration> platform_configuration, 
  6.     fml::WeakPtr<SnapshotDelegate> snapshot_delegate, 
  7.     fml::WeakPtr<HintFreedDelegate> hint_freed_delegate, 
  8.     fml::WeakPtr<IOManager> io_manager, 
  9.     fml::RefPtr<SkiaUnrefQueue> skia_unref_queue, 
  10.     fml::WeakPtr<ImageDecoder> image_decoder, 
  11.     std::string advisory_script_uri, 
  12.     std::string advisory_script_entrypoint, 
  13.     Flags isolate_flags, 
  14.     const fml::closure& isolate_create_callback, 
  15.     const fml::closure& isolate_shutdown_callback, 
  16.     std::optional<std::string> dart_entrypoint, 
  17.     std::optional<std::string> dart_entrypoint_library, 
  18.     std::unique_ptr<IsolateConfiguration> isolate_configration) { 
  19.      
  20.  ...删除代码 
  21.   
  22.  ///这里创建了一个 isolate 但是非运行的 
  23.   auto isolate = CreateRootIsolate(settings,                           // 
  24.                                    isolate_snapshot,                   // 
  25.                                    task_runners,                       // 
  26.                                    std::move(platform_configuration),  // 
  27.                                    snapshot_delegate,                  // 
  28.                                    hint_freed_delegate,                // 
  29.                                    io_manager,                         // 
  30.                                    skia_unref_queue,                   // 
  31.                                    image_decoder,                      // 
  32.                                    advisory_script_uri,                // 
  33.                                    advisory_script_entrypoint,         // 
  34.                                    isolate_flags,                      // 
  35.                                    isolate_create_callback,            // 
  36.                                    isolate_shutdown_callback           // 
  37.                                    ) 
  38.                      .lock(); 
  39.  
  40.    
  41.   ...删除部分代码 (主要是对 isolate的状态检查) 
  42.   
  43.  //注意这个方法 
  44.   if (!isolate->RunFromLibrary(dart_entrypoint_library,       // 
  45.                                dart_entrypoint,               // 
  46.                                settings.dart_entrypoint_args  // 
  47.                                )) { 
  48.     FML_LOG(ERROR) << "Could not run the run main Dart entrypoint."; 
  49.     return {}; 
  50.   } 
  51.  
  52.   if (settings.root_isolate_shutdown_callback) { 
  53.     isolate->AddIsolateShutdownCallback( 
  54.         settings.root_isolate_shutdown_callback); 
  55.   } 
  56.  
  57.   shutdown_on_error.Release(); 
  58.  
  59.   return isolate; 

创建isolate后,进一步调用RunFromLibrary 这个方法:

tip:注意这个过程携带的参数。

  1. bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name, 
  2.                                  std::optional<std::string> entrypoint, 
  3.                                  const std::vector<std::string>& args) { 
  4.   TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary"); 
  5.   /// isolate 非准备状态,直接退出 
  6.   if (phase_ != Phase::Ready) { 
  7.     return false; 
  8.   } 
  9.  
  10.   tonic::DartState::Scope scope(this); 
  11.    
  12.  ...删除部分代码 
  13.   
  14.   ///这里进一步调用了 InvokeMainEntrypoint方法 
  15.   if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) { 
  16.     return false; 
  17.   } 
  18.  ///设置 isolate为 运行状态 
  19.   phase_ = Phase::Running; 
  20.  
  21.   return true; 

InvokeMainEntrypoint:

  1. [[nodiscard]] static bool InvokeMainEntrypoint( 
  2.     Dart_Handle user_entrypoint_function, 
  3.     Dart_Handle args) { 
  4.   ...删除部分代码 
  5.   ///这里,会通过DartInvokeField 
  6.   ///拉起我们的 main.dart中的main()方法并开始flutter的运行 
  7.   /// PS :这个入口点也可以自定义,不过很少用到 
  8.   if (tonic::LogIfError(tonic::DartInvokeField( 
  9.           Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned", 
  10.           {start_main_isolate_function, user_entrypoint_function, args}))) { 
  11.     FML_LOG(ERROR) << "Could not invoke the main entrypoint."; 
  12.     return false; 
  13.   } 
  14.  
  15.   return true; 

小结

到了这里,整个flutter的启动从平台到native所作的工作基本就简要的介绍完了。

本人也是刚开始对native进行了解,以进一步对flutter的运行原理有所了解,如果有错误之处,还请指出,谢谢。

用户评论