·  阅读

在Android中,应用的启动都是从 Application 的创建开始,所以基本上都会来自定义实现 Application 并在该类中进行一些初始化操作,如推送、分享、支付等。 Flutter 也不例外,也会在自定义的 Application 中进行 Engine 的初始化操作。

1、Engine的初始化

FlutterApplication 就是一个自定义的 Application 类,在该类中进行了 Engine 的初始化,代码如下。

public class FlutterApplication extends Application {
    @Override
    @CallSuper
    public void onCreate() {
        super.onCreate();
        //初始化
        FlutterMain.startInitialization(this);
复制代码

再来看 FlutterMain 类的 startInitialization 方法,因为 Engine 的初始化是通过该方法开始的。

public static void startInitialization(@NonNull Context applicationContext) {
    //如果在进行Robolectric测试,则暂不进行初始化操作
    if (isRunningInRobolectricTest) {
        return;
    FlutterLoader.getInstance().startInitialization(applicationContext);
复制代码

startInitialization 方法中又调用了 FlutterLoader startInitialization 方法,该方法是 Engine 初始化的具体实现。

public class FlutterLoader {
    public void startInitialization(@NonNull Context applicationContext) {
        startInitialization(applicationContext, new Settings());
    public void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) {
        //不允许多次初始化
        if (this.settings != null) {
          return;
        //必须在主线程中初始化
        if (Looper.myLooper() != Looper.getMainLooper()) {
          throw new IllegalStateException("startInitialization must be called on the main thread");
        this.settings = settings;
        //当前时间
        long initStartTimestampMillis = SystemClock.uptimeMillis();
        //初始化配置
        initConfig(applicationContext);
        //初始化资源
        initResources(applicationContext);
        //加载flutter.so动态库
        System.loadLibrary("flutter");
        //初始化一个类VsyncWaiter,主要是同步Android的VSYNC信号给Engine
        VsyncWaiter
            .getInstance((WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE))
            .init();
        //记录Engine的初始化时间
        long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;
        FlutterJNI.nativeRecordStartTimestamp(initTimeMillis);
复制代码

这里重点在于 flutter.so 动态库的加载。由于Java VM在加载动态库时第一个调用的是 JNI_OnLoad 函数,所以就先来看该函数的实现。

[-> flutter/shell/platform/android/library_loader.cc]

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  //Initialize the Java VM.
  //将vm作为一个全局变量
  fml::jni::InitJavaVM(vm);
  //获取当前线程的env
  JNIEnv* env = fml::jni::AttachCurrentThread();
  bool result = false;
  //Register FlutterMain.
  //Java Native方法的注册,主要是注册了FlutterJNI类的nativeInit、nativeRecordStartTimestamp方法。
  result = flutter::FlutterMain::Register(env);
  //Register PlatformView
  //Java Native方法的注册
  result = flutter::PlatformViewAndroid::Register(env);
  //Register VSyncWaiter.
  //Java Native方法的注册
  result = flutter::VsyncWaiterAndroid::Register(env);
  return JNI_VERSION_1_4;
复制代码

到此, Engine 就已经成功初始化,流程图如下。

2、Engine对象的创建

Engine 初始化成功后,就可以来创建 Engine 。在 Android 中, Engine 是从 FlutterActivity onCreate 方法开始创建的,代码如下。

public class FlutterActivity extends Activity implements FlutterView.Provider, PluginRegistry, ViewFactory {
    private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);
    private final FlutterActivityEvents eventDelegate = delegate;
    private final FlutterView.Provider viewProvider = delegate;
    private final PluginRegistry pluginRegistry = delegate;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        eventDelegate.onCreate(savedInstanceState);
复制代码

顾名思义, FlutterActivityDelegate 是一个代理类,全权负责 FlutterActivity 的所有工作。由于 Activity 在其生命周期内调用的第一个方法是 onCreate 。所以来看类 FlutterActivityDelegate 中的 onCreate 方法的具体实现。

public final class FlutterActivityDelegate
        implements FlutterActivityEvents,
                   FlutterView.Provider,
                   PluginRegistry {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(0x40000000);
            window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
        String[] args = getArgsFromIntent(activity.getIntent());
        FlutterMain.ensureInitializationComplete(activity.getApplicationContext(), args);
        //是否自定义FlutterView,默认不需要自定义
        flutterView = viewFactory.createFlutterView(activity);
        if (flutterView == null) {
            //是否自定义FlutterNativeView,默认不自定义
            FlutterNativeView nativeView = viewFactory.createFlutterNativeView();
            //创建flutterView
            flutterView = new FlutterView(activity, null, nativeView);
            //flutterView铺满整个屏幕
            flutterView.setLayoutParams(matchParent);
            activity.setContentView(flutterView);
            //创建launchView,launchView是Flutter加载第一帧前的展示View
            launchView = createLaunchView();
            if (launchView != null) {
                addLaunchView();
        if (loadIntent(activity.getIntent())) {
            return;
        //获取flutter代码路径
        String appBundlePath = FlutterMain.findAppBundlePath();
        if (appBundlePath != null) {
            //运行Flutter代码
            runBundle(appBundlePath);
复制代码

onCreate 方法中,主要做了以下两件事。

  • 创建了一个 FlutterView ,该View是Flutter界面在Android端的载体。
  • Flutter代码的运行,其实现原理后面再详解。
  • 先来看 FlutterView 的创建,它继承自 SurfaceView ,代码如下。

    public class FlutterView extends SurfaceView implements BinaryMessenger, TextureRegistry {
        public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
            super(context, attrs);
            Activity activity = getActivity(getContext());
            if (activity == null) {
                throw new IllegalArgumentException("Bad context");
            if (nativeView == null) {
                //创建FlutterNativeView对象
                mNativeView = new FlutterNativeView(activity.getApplicationContext());
            } else {
                mNativeView = nativeView;
    复制代码

    FlutterView 中,会创建一个 FlutterNativeView 对象,其构造函数的实现如下。

    public class FlutterNativeView implements BinaryMessenger {
        public FlutterNativeView(@NonNull Context context) {
            this(context, false);
        public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
            mContext = context;
            //创建FlutterPluginRegistry对象
            mPluginRegistry = new FlutterPluginRegistry(this, context);
            //创建FlutterJNI对象
            mFlutterJNI = new FlutterJNI();
            mFlutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
            //创建DartExecutor对象,该对象主要用于Android与Flutter间的通信,如生命周期。
            this.dartExecutor = new DartExecutor(mFlutterJNI, context.getAssets());
            //添加Engine生命周期监听
            mFlutterJNI.addEngineLifecycleListener(new EngineLifecycleListenerImpl());
            //执行attach方法
            attach(this, isBackgroundView);
            assertAttached();
        private void attach(FlutterNativeView view, boolean isBackgroundView) {
            mFlutterJNI.attachToNative(isBackgroundView);
            dartExecutor.onAttachedToJNI();
    //主要是用于Android与Native间的相互调用
    public class FlutterJNI {
      @UiThread
      public void attachToNative(boolean isBackgroundView) {
        nativePlatformViewId = nativeAttach(this, isBackgroundView);
      //native方法
      private native long nativeAttach(@NonNull FlutterJNI flutterJNI, boolean isBackgroundView);
    复制代码

    这里重点在于 attach 方法,该方法会通过 FlutterJNI nativeAttach 方法来进行UI、GPU、IO等线程的创建、Dart VM的创建及 Engine 对象的创建等。下面先来看 nativeAttach 方法在 Engine 中的对应实现。

    [-> flutter/shell/platform/android/platform_view_android_jni.cc]

    static jlong AttachJNI(JNIEnv* env,
                           jclass clazz,
                           jobject flutterJNI,
                           jboolean is_background_view) {
      fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
      //AndroidShellHolder对象的创建
      auto shell_holder = std::make_unique<AndroidShellHolder>(
          FlutterMain::Get().GetSettings(), java_object, is_background_view);
    复制代码

    AttachJNI 函数中主要是创建一个 AndroidShellHolder 对象,它的构造函数实现如下。

    [-> flutter/shell/platform/android/android_shell_holder.cc]

    AndroidShellHolder::AndroidShellHolder(
        flutter::Settings settings,
        fml::jni::JavaObjectWeakGlobalRef java_object,
        bool is_background_view)
        : settings_(std::move(settings)), java_object_(java_object) {
      static size_t shell_count = 1;
      auto thread_label = std::to_string(shell_count++);
      //创建目标线程
      if (is_background_view) {
        //仅创建UI线程
        thread_host_ = {thread_label, ThreadHost::Type::UI};
      } else {
        //创建UI线程、GPU线程及IO线程
        thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
                                          ThreadHost::Type::IO};
      // Detach from JNI when the UI and GPU threads exit.
      auto jni_exit_task([key = thread_destruct_key_]() {
        FML_CHECK(pthread_setspecific(key, reinterpret_cast<void*>(1)) == 0);
      thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task);
      if (!is_background_view) {
        thread_host_.gpu_thread->GetTaskRunner()->PostTask(jni_exit_task);
      fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
      Shell::CreateCallback<PlatformView> on_create_platform_view =
          [is_background_view, java_object, &weak_platform_view](Shell& shell) {
            std::unique_ptr<PlatformViewAndroid> platform_view_android;
            //创建PlatformViewAndroid对象
            if (is_background_view) {
              //不具备渲染能力且在后台运行
              platform_view_android = std::make_unique<PlatformViewAndroid>(
                  shell,                   // delegate
                  shell.GetTaskRunners(),  // task runners
                  java_object              // java object handle for JNI interop
            } else {
              //具备渲染能力
              platform_view_android = std::make_unique<PlatformViewAndroid>(
                  shell,                   // delegate
                  shell.GetTaskRunners(),  // task runners
                  java_object,             // java object handle for JNI interop
                  shell.GetSettings()
                      .enable_software_rendering  // use software rendering
            weak_platform_view = platform_view_android->GetWeakPtr();
            return platform_view_android;
      Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
        //创建删格化器
        return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
      //将当前线程(Android主线程)作为平台线程(platform thread)并确保已经初始化Message Loop
      fml::MessageLoop::EnsureInitializedForCurrentThread();
      fml::RefPtr<fml::TaskRunner> gpu_runner;
      fml::RefPtr<fml::TaskRunner> ui_runner;
      fml::RefPtr<fml::TaskRunner> io_runner;
      fml::RefPtr<fml::TaskRunner> platform_runner =
          fml::MessageLoop::GetCurrent().GetTaskRunner();
      if (is_background_view) {
        auto single_task_runner = thread_host_.ui_thread->GetTaskRunner();
        gpu_runner = single_task_runner;
        ui_runner = single_task_runner;
        io_runner = single_task_runner;
      } else {
        gpu_runner = thread_host_.gpu_thread->GetTaskRunner();
        ui_runner = thread_host_.ui_thread->GetTaskRunner();
        io_runner = thread_host_.io_thread->GetTaskRunner();
      //创建TaskRunners对象
      flutter::TaskRunners task_runners(thread_label,     // label
                                        platform_runner,  // platform
                                        gpu_runner,       // gpu
                                        ui_runner,        // ui
                                        io_runner         // io
      //创建Shell对象
      shell_ =
          Shell::Create(task_runners,             // task runners
                        GetDefaultWindowData(),   // window data
                        settings_,                // settings
                        on_create_platform_view,  // platform view create callback
                        on_create_rasterizer      // rasterizer create callback
      platform_view_ = weak_platform_view;
      FML_DCHECK(platform_view_);
      is_valid_ = shell_ != nullptr;
      if (is_valid_) {
        //降低GPU线程的优先级
        task_runners.GetGPUTaskRunner()->PostTask([]() {
          //Android将-8描述为“最重要的显示线程,用于合成屏幕和检索输入事件”。 保守地将GPU线程设置为比其优先级稍低的优先级。
          //将GPU线程优先级设为-5。
          if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
            //如果无法将GPU线程优先级设为-5,那么继续将GPU线程优先级设为-2。
            if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
              FML_LOG(ERROR) << "Failed to set GPU task runner priority";
        //将UI线程优先级设为-1。
        task_runners.GetUITaskRunner()->PostTask([]() {
          if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
            FML_LOG(ERROR) << "Failed to set UI task runner priority";
    复制代码

    上面代码还是比较多的,但主要做了以下几件事。

  • 目标线程的创建,如果 is_background_view 为true,则仅会创建UI线程,否则会创建UI、GPU及IO线程。 is_background_view 默认为false。
  • 将当前线程(Android主线程)作为平台线程(platform thread)并确保已经初始化Message Loop。
  • Shell 对象的创建。
  • GPU线程及UI线程优先级的修改。
  • 从上面可以得出Android主线程(UI线程)是作为 Flutter 的平台线程(platform thread)存在的,与 Flutter 的UI线程不是同一线程,所以不要将Android的主线程(UI线程)与 Flutter 的UI线程搞混。

    再来看 Shell 对象的创建。

    [-> flutter/shell/common/shell.cc]

    std::unique_ptr<Shell> Shell::Create(
        TaskRunners task_runners,
        const WindowData window_data,
        Settings settings,
        Shell::CreateCallback<PlatformView> on_create_platform_view,
        Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
      PerformInitializationTasks(settings);
      PersistentCache::SetCacheSkSL(settings.cache_sksl);
      //Dart虚拟机的创建
      auto vm = DartVMRef::Create(settings);
      auto vm_data = vm->GetVMData();
      return Shell::Create(std::move(task_runners),        //
                           std::move(window_data),         //
                           std::move(settings),            //
                           vm_data->GetIsolateSnapshot(),  // isolate snapshot
                           on_create_platform_view,        //
                           on_create_rasterizer,           //
                           std::move(vm)                   //
    复制代码

    Create 函数中,会进行Dart VM的创建,其创建流程参考 Flutter之Dart虚拟机启动

    再来看 Create 函数,在该函数中会调用 CreateShellOnPlatformThread 函数,顾名思义, CreateShellOnPlatformThread 函数就是在平台线程中创建 Shell 对象。

    [-> flutter/shell/common/shell.cc]

    std::unique_ptr<Shell> Shell::Create(
        TaskRunners task_runners,
        const WindowData window_data,
        Settings settings,
        fml::RefPtr<const DartSnapshot> isolate_snapshot,
        const Shell::CreateCallback<PlatformView>& on_create_platform_view,
        const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
        DartVMRef vm) {
      fml::AutoResetWaitableEvent latch;
      std::unique_ptr<Shell> shell;
      fml::TaskRunner::RunNowOrPostTask(
          task_runners.GetPlatformTaskRunner(),
          fml::MakeCopyable([&latch,                                          //
                             vm = std::move(vm),                              //
                             &shell,                                          //
                             task_runners = std::move(task_runners),          //
                             window_data,                                     //
                             settings,                                        //
                             isolate_snapshot = std::move(isolate_snapshot),  //
                             on_create_platform_view,                         //
                             on_create_rasterizer                             //
      ]() mutable {
            //在平台线程中创建Shell对象
            shell = CreateShellOnPlatformThread(std::move(vm),
                                                std::move(task_runners),      //
                                                window_data,                  //
                                                settings,                     //
                                                std::move(isolate_snapshot),  //
                                                on_create_platform_view,      //
                                                on_create_rasterizer          //
            //锁唤醒
            latch.Signal();
      //锁等待
      latch.Wait();
      return shell;
    std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
        DartVMRef vm,
        TaskRunners task_runners,
        const WindowData window_data,
        Settings settings,
        fml::RefPtr<const DartSnapshot> isolate_snapshot,
        const Shell::CreateCallback<PlatformView>& on_create_platform_view,
        const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
      //创建Shell对象
      auto shell =
          std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
      //在GPU线程上创建光栅化器。
      std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
      auto rasterizer_future = rasterizer_promise.get_future();
      std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise;
      auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
      fml::TaskRunner::RunNowOrPostTask(
          task_runners.GetGPUTaskRunner(), [&rasterizer_promise,  //
                                            &snapshot_delegate_promise,
                                            on_create_rasterizer,  //
                                            shell = shell.get()    //
      ]() {
            std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
            snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
            rasterizer_promise.set_value(std::move(rasterizer));
      //在平台线程(platform thread)也就是Android主线程中创建platform view
      auto platform_view = on_create_platform_view(*shell.get());
      if (!platform_view || !platform_view->GetWeakPtr()) {
        return nullptr;
      //由platform view创建vsync waiter,
      auto vsync_waiter = platform_view->CreateVSyncWaiter();
      if (!vsync_waiter) {
        return nullptr;
      //在IO线程上创建IO manager。 必须先初始化IO manager,因为它具有其他子系统依赖的状态。 必须首先引导它,并获取必要的引用以初始化其他子系统。
      std::promise<std::unique_ptr<ShellIOManager>> io_manager_promise;
      auto io_manager_future = io_manager_promise.get_future();
      std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise;
      auto weak_io_manager_future = weak_io_manager_promise.get_future();
      std::promise<fml::RefPtr<SkiaUnrefQueue>> unref_queue_promise;
      auto unref_queue_future = unref_queue_promise.get_future();
      auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
      // TODO(gw280): The WeakPtr here asserts that we are derefing it on the
      // same thread as it was created on. We are currently on the IO thread
      // inside this lambda but we need to deref the PlatformView, which was
      // constructed on the platform thread.
      // https://github.com/flutter/flutter/issues/42948
      fml::TaskRunner::RunNowOrPostTask(
          io_task_runner,
          [&io_manager_promise,                                               //
           &weak_io_manager_promise,                                          //
           &unref_queue_promise,                                              //
           platform_view = platform_view->GetWeakPtr(),                       //
           io_task_runner,                                                    //
           is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch()  //
      ]() {
            auto io_manager = std::make_unique<ShellIOManager>(
                platform_view.getUnsafe()->CreateResourceContext(),
                is_backgrounded_sync_switch, io_task_runner);
            weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
            unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
            io_manager_promise.set_value(std::move(io_manager));
      // Send dispatcher_maker to the engine constructor because shell won't have
      // platform_view set until Shell::Setup is called later.
      auto dispatcher_maker = platform_view->GetDispatcherMaker();
      //在Flutter的UI线程中创建engine对象
      std::promise<std::unique_ptr<Engine>> engine_promise;
      auto engine_future = engine_promise.get_future();
      fml::TaskRunner::RunNowOrPostTask(
          shell->GetTaskRunners().GetUITaskRunner(),
          fml::MakeCopyable([&engine_promise,                                 //
                             shell = shell.get(),                             //
                             &dispatcher_maker,                               //
                             &window_data,                                    //
                             isolate_snapshot = std::move(isolate_snapshot),  //
                             vsync_waiter = std::move(vsync_waiter),          //
                             &weak_io_manager_future,                         //
                             &snapshot_delegate_future,                       //
                             &unref_queue_future                              //
      ]() mutable {
            const auto& task_runners = shell->GetTaskRunners();
            //在UI线程创建animator,这里主要是为了将平台的vsync信号同步给animator
            auto animator = std::make_unique<Animator>(*shell, task_runners,
                                                       std::move(vsync_waiter));
            //Engine对象的创建,此时已经切换到Flutter的UI线程
            engine_promise.set_value(std::make_unique<Engine>(
                *shell,                         //
                dispatcher_maker,               //
                *shell->GetDartVM(),            //
                std::move(isolate_snapshot),    //
                task_runners,                   //
                window_data,                    //
                shell->GetSettings(),           //
                std::move(animator),            //
                weak_io_manager_future.get(),   //
                unref_queue_future.get(),       //
                snapshot_delegate_future.get()  //
      //启动Shell
      if (!shell->Setup(std::move(platform_view),  //
                        engine_future.get(),       //
                        rasterizer_future.get(),   //
                        io_manager_future.get())   //
        return nullptr;
      return shell;
    复制代码

    CreateShellOnPlatformThread 函数的实现还是蛮复杂的,但主要还是做了以下几件事。

  • 在平台线程中创建一个 Shell 对象。
  • 在GPU线程创建删格化器, Flutter 在绘制完成后,会将数据给它进行删格化处理。关于 Flutter 的绘制原理可以参考 Flutter的绘制流程简述 这篇文章。
  • 在平台线程中创建一个 PlatformViewAndroid 对象。如果 is_background_view 为true,会创建一个具备渲染能力的 PlatformViewAndroid 对象,否则创建的是一个不具备渲染能力且在后台执行的 PlatformViewAndroid 对象。
  • 通过 PlatformView 来创建vsync waiter,主要用于VSYNC信号的同步。
  • 在IO线程创建IO manager。
  • 在Flutter的UI线程创建Engine对象。
  • 在平台线程启动 Shell ,调用 Shell 对象的 Setup 函数。
  • 这里先忽略其他,主要来看 Engine 对象的创建。在其构造函数中,会创建一个 RuntimeController 对象。

    Engine::Engine(Delegate& delegate,
                   const PointerDataDispatcherMaker& dispatcher_maker,
                   DartVM& vm,
                   fml::RefPtr<const DartSnapshot> isolate_snapshot,
                   TaskRunners task_runners,
                   const WindowData window_data,
                   Settings settings,
                   std::unique_ptr<Animator> animator,
                   fml::WeakPtr<IOManager> io_manager,
                   fml::RefPtr<SkiaUnrefQueue> unref_queue,
                   fml::WeakPtr<SnapshotDelegate> snapshot_delegate)
        : delegate_(delegate),
          settings_(std::move(settings)),
          animator_(std::move(animator)),
          activity_running_(true),
          have_surface_(false),
          image_decoder_(task_runners,
                         vm.GetConcurrentWorkerTaskRunner(),
                         io_manager),
          task_runners_(std::move(task_runners)),
          weak_factory_(this) {
      //RuntimeController对象的创建
      runtime_controller_ = std::make_unique<RuntimeController>(
          *this,                        // runtime delegate
          &vm,                          // VM
          std::move(isolate_snapshot),  // isolate snapshot
          task_runners_,                // task runners
          std::move(snapshot_delegate),
          std::move(io_manager),                 // io manager
          std::move(unref_queue),                // Skia unref queue
          image_decoder_.GetWeakPtr(),           // image decoder
          settings_.advisory_script_uri,         // advisory script uri
          settings_.advisory_script_entrypoint,  // advisory script entrypoint
          settings_.idle_notification_callback,  // idle notification callback
          window_data,                           // window data
          settings_.isolate_create_callback,     // isolate create callback
          settings_.isolate_shutdown_callback,   // isolate shutdown callback
          settings_.persistent_isolate_data      // persistent isolate data
      pointer_data_dispatcher_ = dispatcher_maker(*this);
    复制代码

    这里的 RuntimeController 是一个非常重要的对象,在后面很多地方都会用到它。由于篇幅原因,先来看一下从 FlutterActivity RuntimeController 对象创建的流程图。

    2.1、RootIsolate对象的创建

    再来看 RuntimeController 对象的创建。

    RuntimeController::RuntimeController(
        RuntimeDelegate& p_client,
        DartVM* p_vm,
        fml::RefPtr<const DartSnapshot> p_isolate_snapshot,
        TaskRunners p_task_runners,
        fml::WeakPtr<SnapshotDelegate> p_snapshot_delegate,
        fml::WeakPtr<IOManager> p_io_manager,
        fml::RefPtr<SkiaUnrefQueue> p_unref_queue,
        fml::WeakPtr<ImageDecoder> p_image_decoder,
        std::string p_advisory_script_uri,
        std::string p_advisory_script_entrypoint,
        const std::function<void(int64_t)>& idle_notification_callback,
        const WindowData& p_window_data,
        const fml::closure& p_isolate_create_callback,
        const fml::closure& p_isolate_shutdown_callback,
        std::shared_ptr<const fml::Mapping> p_persistent_isolate_data)
        : client_(p_client),
          vm_(p_vm),
          isolate_snapshot_(std::move(p_isolate_snapshot)),
          task_runners_(p_task_runners),
          snapshot_delegate_(p_snapshot_delegate),
          io_manager_(p_io_manager),
          unref_queue_(p_unref_queue),
          image_decoder_(p_image_decoder),
          advisory_script_uri_(p_advisory_script_uri),
          advisory_script_entrypoint_(p_advisory_script_entrypoint),
          idle_notification_callback_(idle_notification_callback),
          window_data_(std::move(p_window_data)),
          isolate_create_callback_(p_isolate_create_callback),
          isolate_shutdown_callback_(p_isolate_shutdown_callback),
          persistent_isolate_data_(std::move(p_persistent_isolate_data)) {
      //创建RootIsolate
      auto strong_root_isolate =
          DartIsolate::CreateRootIsolate(vm_->GetVMData()->GetSettings(),  //
                                         isolate_snapshot_,                //
                                         task_runners_,                    //
                                         std::make_unique<Window>(this),   //
                                         snapshot_delegate_,               //
                                         io_manager_,                      //
                                         unref_queue_,                     //
                                         image_decoder_,                   //
                                         p_advisory_script_uri,            //
                                         p_advisory_script_entrypoint,     //
                                         nullptr,                          //
                                         isolate_create_callback_,         //
                                         isolate_shutdown_callback_        //
              .lock();
    复制代码

    在构造函数中,会调用 CreateRootIsolate 函数来创建一个 isolate 作为根 Isolate

    std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
        const Settings& settings,
        fml::RefPtr<const DartSnapshot> isolate_snapshot,
        TaskRunners task_runners,
        std::unique_ptr<Window> window,
        fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
        fml::WeakPtr<IOManager> io_manager,
        fml::RefPtr<SkiaUnrefQueue> unref_queue,
        fml::WeakPtr<ImageDecoder> image_decoder,
        std::string advisory_script_uri,
        std::string advisory_script_entrypoint,
        Dart_IsolateFlags* flags,
        const fml::closure& isolate_create_callback,
        const fml::closure& isolate_shutdown_callback) {
      //创建isolate对象
      Dart_Isolate vm_isolate =
          CreateDartIsolateGroup(std::move(isolate_group_data),
                                 std::move(isolate_data), flags, error.error());
      std::shared_ptr<DartIsolate>* root_isolate_data =
          static_cast<std::shared_ptr<DartIsolate>*>(Dart_IsolateData(vm_isolate));
      (*root_isolate_data)->SetWindow(std::move(window));
      return (*root_isolate_data)->GetWeakIsolatePtr();
    复制代码

    再来看 CreateDartIsolateGroup 函数,该函数主要做了两件事。

  • 通过Dart VM来创建isolate对象,并将该isolate对象作为root isolate。
  • 初始化isolate对象。
  • Dart_Isolate DartIsolate::CreateDartIsolateGroup(
        std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
        std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
        Dart_IsolateFlags* flags,
        char** error) {
      //通过Dart VM创建一个isolate对象
      Dart_Isolate isolate = Dart_CreateIsolateGroup(
          (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
          (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
          (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
          (*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(),
          flags, isolate_group_data.get(), isolate_data.get(), error);
      if (isolate == nullptr) {
        return nullptr;
      // Ownership of the isolate data objects has been transferred to the Dart VM.
      std::shared_ptr<DartIsolate> embedder_isolate(*isolate_data);
      isolate_group_data.release();
      isolate_data.release();
      //初始化isolate对象
      if (!InitializeIsolate(std::move(embedder_isolate), isolate, error)) {
        return nullptr;
      return isolate;
    复制代码

    先来看 Dart_CreateIsolateGroup 函数在Dart VM的实现,在其实现函数中会创建 isolate 对象。

    Dart_CreateIsolateGroup(const char* script_uri,
                            const char* name,
                            const uint8_t* snapshot_data,
                            const uint8_t* snapshot_instructions,
                            Dart_IsolateFlags* flags,
                            void* isolate_group_data,
                            void* isolate_data,
                            char** error) {
      Dart_IsolateFlags api_flags;
      if (flags == nullptr) {
        Isolate::FlagsInitialize(&api_flags);
        flags = &api_flags;
      const char* non_null_name = name == nullptr ? "isolate" : name;
      std::unique_ptr<IsolateGroupSource> source(
          new IsolateGroupSource(script_uri, non_null_name, snapshot_data,
                                 snapshot_instructions, nullptr, -1, *flags));
      auto group = new IsolateGroup(std::move(source), isolate_group_data);
      IsolateGroup::RegisterIsolateGroup(group);
      Dart_Isolate isolate =
          CreateIsolate(group, non_null_name, isolate_data, error);
      if (isolate != nullptr) {
        group->set_initial_spawn_successful();
      return isolate;
    复制代码

    CreateIsolate 函数就会创建一个 isolate 对象,关于后续的 isolate 对象的创建及 isolate 的更多内容可以去阅读 深入理解Isolate 这篇文章。

    再来看 isolate 对象的初始化函数—— InitializeIsolate 的实现。

    bool DartIsolate::InitializeIsolate(
        std::shared_ptr<DartIsolate> embedder_isolate,
        Dart_Isolate isolate,
        char** error) {
      if (!embedder_isolate->Initialize(isolate)) {//初始化
        *error = fml::strdup("Embedder could not initialize the Dart isolate.");
    9999    return false;
      //isolate加载library
      if (!embedder_isolate->LoadLibraries()) {
        *error = fml::strdup(
            "Embedder could not load libraries in the new Dart isolate.");
        return false;
      // Root isolates will be setup by the engine and the service isolate (which is
      // also a root isolate) by the utility routines in the VM. However, secondary
      // isolates will be run by the VM if they are marked as runnable.
      if (!embedder_isolate->IsRootIsolate()) {
        auto child_isolate_preparer =
            embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer();
        if (!child_isolate_preparer(embedder_isolate.get())) {
          *error = fml::strdup("Could not prepare the child isolate to run.");
          return false;
      return true;
    //初始化
    bool DartIsolate::Initialize(Dart_Isolate dart_isolate) {
      if (phase_ != Phase::Uninitialized) {
        return false;
      if (dart_isolate == nullptr) {
        return false;
      if (Dart_CurrentIsolate() != dart_isolate) {
        return false;
      //从这里开始,可以安全的使用isolate
      SetIsolate(dart_isolate);
      // We are entering a new scope (for the first time since initialization) and
      // we want to restore the current scope to null when we exit out of this
      // method. This balances the implicit Dart_EnterIsolate call made by
      // Dart_CreateIsolateGroup (which calls the Initialize).
      Dart_ExitIsolate();
      tonic::DartIsolateScope scope(isolate());
      //设置UI线程的消息处理器
      SetMessageHandlingTaskRunner(GetTaskRunners().GetUITaskRunner());
      if (tonic::LogIfError(
              Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))) {
        return false;
      if (!UpdateThreadPoolNames()) {
        return false;
      //初始化完成
      phase_ = Phase::Initialized;
      return true;
    void DartIsolate::SetMessageHandlingTaskRunner(
        fml::RefPtr<fml::TaskRunner> runner) {
      if (!IsRootIsolate() || !runner) {
        return;
      message_handling_task_runner_ = runner;
      //设置消息处理器
      message_handler().Initialize(
          [runner](std::function<void()> task) { runner->PostTask(task); });
    复制代码

    最终在 SetMessageHandlingTaskRunner 函数中将 UITaskRunner 设置为 Flutter 中UI线程的消息处理器,进行UI线程中消息的分发并处理。也就是说在 RootIsolate 中,消息并不是通过线程池中来分发及处理的,所以不要在UI线程的消息中进行耗时操作,否则影响UI绘制。其实在Android平台上的 Flutter 的消息处理机制与 Android 中的消息机制类似,都是使用的Android平台的 Looper 。更多内容后面再来一一讲解。

    void DartMessageHandler::Initialize(TaskDispatcher dispatcher) {
      // Only can be called once.
      TONIC_CHECK(!task_dispatcher_ && dispatcher);
      task_dispatcher_ = dispatcher;
      Dart_SetMessageNotifyCallback(MessageNotifyCallback);
    复制代码

    Dart_SetMessageNotifyCallback 中其实就是给 RootIsolate 设置消息通知回调,代码如下。

    DART_EXPORT void Dart_SetMessageNotifyCallback(
        Dart_MessageNotifyCallback message_notify_callback) {
      Isolate* isolate = Isolate::Current();
      CHECK_ISOLATE(isolate);
        NoSafepointScope no_safepoint_scope;
        isolate->set_message_notify_callback(message_notify_callback);
      if (message_notify_callback != nullptr && isolate->HasPendingMessages()) {
        ::Dart_ExitIsolate();
        // If a new handler gets installed and there are pending messages in the
        // queue (e.g. OOB messages for doing vm service work) we need to notify
        // the newly registered callback, otherwise the embedder might never get
        // notified about the pending messages.
        message_notify_callback(Api::CastIsolate(isolate));
        ::Dart_EnterIsolate(Api::CastIsolate(isolate));
    复制代码

    关于 RootIsolate 的相关调用流程图如下。 到此,一个 Engine 对象就已经创建完毕。再回到 Shell 中,来看 Shell Setup 函数是如何启动的。代码如下。

    bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
                      std::unique_ptr<Engine> engine,
                      std::unique_ptr<Rasterizer> rasterizer,
                      std::unique_ptr<ShellIOManager> io_manager) {
      if (is_setup_) {
        return false;
      //platform_view、engine、rasterizer及io_manager只要有一个创建失败,Shell启动就会失败
      if (!platform_view || !engine || !rasterizer || !io_manager) {
        return false;
      platform_view_ = std::move(platform_view);
      engine_ = std::move(engine);
      rasterizer_ = std::move(rasterizer);
      io_manager_ = std::move(io_manager);
      // The weak ptr must be generated in the platform thread which owns the unique
      // ptr.
      weak_engine_ = engine_->GetWeakPtr();
      weak_rasterizer_ = rasterizer_->GetWeakPtr();
      weak_platform_view_ = platform_view_->GetWeakPtr();
      is_setup_ = true;
      vm_->GetServiceProtocol()->AddHandler(this, GetServiceProtocolDescription());
      PersistentCache::GetCacheForProcess()->AddWorkerTaskRunner(
          task_runners_.GetIOTaskRunner());
      PersistentCache::GetCacheForProcess()->SetIsDumpingSkp(
          settings_.dump_skp_on_shader_compilation);
      // TODO(gw280): The WeakPtr here asserts that we are derefing it on the
      // same thread as it was created on. Shell is constructed on the platform
      // thread but we need to call into the Engine on the UI thread, so we need
      // to use getUnsafe() here to avoid failing the assertion.
      // https://github.com/flutter/flutter/issues/42947
      display_refresh_rate_ = weak_engine_.getUnsafe()->GetDisplayRefreshRate();
      return true;
    复制代码

    Setup 函数中主要是检查 Shell 的子组件是否已经初始化,如 Engine platform_view rasterizer io manager 等,然后将这些组件设置为全局。

    如果该函数返回 true 就表示 Engine 已经创建成功。

    3、Engine的运行

    再回到类 FlutterActivityDelegate 中,当 Engine 创建完毕后,再调用 runBundle 方法来执行 Flutter 代码。

    public final class FlutterActivityDelegate
            implements FlutterActivityEvents,
                       FlutterView.Provider,
                       PluginRegistry {
        private void runBundle(String appBundlePath) {
            if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
                FlutterRunArguments args = new FlutterRunArguments();
                //flutter代码路径
                args.bundlePath = appBundlePath;
                //flutter入口函数
                args.entrypoint = "main";
                flutterView.runFromBundle(args);
    复制代码

    先来看 FlutterRunArguments ,它仅有三个字段,如下。

    public class FlutterRunArguments {
      public String bundlePath;
      public String entrypoint;
      public String libraryPath;
    复制代码

    runBundle 方法中调用 FlutterView runFromBundle 方法时,字段 libraryPath 为空。在后面会用到根据 entrypoint libraryPath 有不同实现。

    public class FlutterView extends SurfaceView implements BinaryMessenger, TextureRegistry {
        public void runFromBundle(FlutterRunArguments args) {
          assertAttached();
          preRun();
          //运行flutter代码
          mNativeView.runFromBundle(args);
          postRun();
    public class FlutterNativeView implements BinaryMessenger {
        public void runFromBundle(FlutterRunArguments args) {
            if (args.entrypoint == null) {
                throw new AssertionError("An entrypoint must be specified");
            assertAttached();
            if (applicationIsRunning)
                throw new AssertionError(
                        "This Flutter engine instance is already running an application");
            mFlutterJNI.runBundleAndSnapshotFromLibrary(
                args.bundlePath,
                args.entrypoint,
                args.libraryPath,
                mContext.getResources().getAssets()
            applicationIsRunning = true;
    public class FlutterJNI {
      @UiThread
      public void runBundleAndSnapshotFromLibrary(
          @NonNull String bundlePath,
          @Nullable String entrypointFunctionName,
          @Nullable String pathToEntrypointFunction,
          @NonNull AssetManager assetManager
        ensureRunningOnMainThread();
        ensureAttachedToNative();
        nativeRunBundleAndSnapshotFromLibrary(
            nativePlatformViewId,
            bundlePath,
            entrypointFunctionName,
            pathToEntrypointFunction,
            assetManager
      private native void nativeRunBundleAndSnapshotFromLibrary(
          long nativePlatformViewId,
          @NonNull String bundlePath,
          @Nullable String entrypointFunctionName,
          @Nullable String pathToEntrypointFunction,
          @NonNull AssetManager manager
    复制代码

    nativeRunBundleAndSnapshotFromLibrary 又是一个 native 方法,它在 Engine 中对应的函数实现如下。

    static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
                                                jobject jcaller,
                                                jlong shell_holder,
                                                jstring jBundlePath,
                                                jstring jEntrypoint,
                                                jstring jLibraryUrl,
                                                jobject jAssetManager) {
      //根据配置文件来启动Engine
      ANDROID_SHELL_HOLDER->Launch(std::move(config));
    复制代码

    RunBundleAndSnapshotFromLibrary 主要是对传递的参数进行封装,然后调用 Shell Launch 函数来运行 Engine

    void AndroidShellHolder::Launch(RunConfiguration config) {
      if (!IsValid()) {
        return;
      //根据配置运行Engine
      shell_->RunEngine(std::move(config));
    复制代码

    RunEngine 函数的代码实现如下。

    void Shell::RunEngine(RunConfiguration run_configuration) {
      RunEngine(std::move(run_configuration), nullptr);
    void Shell::RunEngine(
        RunConfiguration run_configuration,
        const std::function<void(Engine::RunStatus)>& result_callback) {
      auto result = [platform_runner = task_runners_.GetPlatformTaskRunner(),                 result_callback](Engine::RunStatus run_result) {
        if (!result_callback) {
          return;
        platform_runner->PostTask(
            [result_callback, run_result]() { result_callback(run_result); });
      //在Flutter的UI线程调用Engine对象的run函数
      fml::TaskRunner::RunNowOrPostTask(
          task_runners_.GetUITaskRunner(),
          fml::MakeCopyable(
              [run_configuration = std::move(run_configuration),
               weak_engine = weak_engine_, result]() mutable {
                if (!weak_engine) {
                  result(Engine::RunStatus::Failure);
                  return;
                //weak_engine是在执行shell的Setup函数时设置的。
                auto run_result = weak_engine->Run(std::move(run_configuration));
                if (run_result == flutter::Engine::RunStatus::Failure) {
                  FML_LOG(ERROR) << "Could not launch engine with configuration.";
                result(run_result);
    复制代码

    通过执行 Engine 对象的 Run 函数,就可以让 Engine 对象跑起来,实现代码如下。

    Engine::RunStatus Engine::Run(RunConfiguration configuration) {
      if (!configuration.IsValid()) {
        return RunStatus::Failure;
      last_entry_point_ = configuration.GetEntrypoint();
      last_entry_point_library_ = configuration.GetEntrypointLibrary();
      //准备并启动Isolate
      auto isolate_launch_status =
          PrepareAndLaunchIsolate(std::move(configuration));
      return isolate_running ? Engine::RunStatus::Success
                             : Engine::RunStatus::Failure;
    复制代码

    下面再来看 PrepareAndLaunchIsolate 函数的实现。

    Engine::RunStatus Engine::PrepareAndLaunchIsolate(
        RunConfiguration configuration) {
      //默认情况下,configuration.GetEntrypointLibrary()为空
      if (configuration.GetEntrypointLibrary().empty()) {
        //运行isolate
        if (!isolate->Run(configuration.GetEntrypoint(),
                          settings_.dart_entrypoint_args)) {
          FML_LOG(ERROR) << "Could not run the isolate.";
          return RunStatus::Failure;
      } else {
        if (!isolate->RunFromLibrary(configuration.GetEntrypointLibrary(),
                                     configuration.GetEntrypoint(),
                                     settings_.dart_entrypoint_args)) {
          FML_LOG(ERROR) << "Could not run the isolate.";
          return RunStatus::Failure;
      return RunStatus::Success;
    复制代码

    默认情况下, configuration.GetEntrypointLibrary() 返回值为空,所以这里会调用 DartIsolate run 函数来运行 isolate

    bool DartIsolate::Run(const std::string& entrypoint_name,
                          const std::vector<std::string>& args,
                          const fml::closure& on_run) {
      if (phase_ != Phase::Ready) {
        return false;
      tonic::DartState::Scope scope(this);
      auto user_entrypoint_function =
          Dart_GetField(Dart_RootLibrary(), tonic::ToDart(entrypoint_name.c_str()));
      auto entrypoint_args = tonic::ToDart(args);
      //调用main方法
      if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
        return false;
      phase_ = Phase::Running;
      if (on_run) {
        on_run();
      return true;
    复制代码

    InvokeMainEntrypoint 顾名思义就是调用 Flutter 项目中的入口函数—— main 方法。

    static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function,
                                     Dart_Handle args) {
      if (tonic::LogIfError(user_entrypoint_function)) {
        FML_LOG(ERROR) << "Could not resolve main entrypoint function.";
        return false;
      Dart_Handle start_main_isolate_function =
          tonic::DartInvokeField(Dart_LookupLibrary(tonic::ToDart("dart:isolate")),
                                 "_getStartMainIsolateFunction", {});
      if (tonic::LogIfError(start_main_isolate_function)) {
        FML_LOG(ERROR) << "Could not resolve main entrypoint trampoline.";
        return false;
      if (tonic::LogIfError(tonic::DartInvokeField(
              Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
              {start_main_isolate_function, user_entrypoint_function, args}))) {
        FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
        return false;
      return true;
    复制代码

    来看 _getStartMainIsolateFunction 函数的实现,它返回了一个 _startMainIsolate 函数。

    @pragma("vm:entry-point", "call")
    Function _getStartMainIsolateFunction() {
      return _startMainIsolate;
    @pragma("vm:entry-point", "call")
    void _startMainIsolate(Function entryPoint, List<String> args) {
      _startIsolate(
          null, // no parent port
          entryPoint,
          args,
          null, // no message
          true, // isSpawnUri
          null, // no control port
          null); // no capabilities
    复制代码

    再来看 _runMainZoned 函数的实现,它就直接执行 _getStartMainIsolateFunction 函数的返回函数 _startMainIsolate

    @pragma('vm:entry-point')
    // ignore: unused_element
    void _runMainZoned(Function startMainIsolateFunction,
                       Function userMainFunction,
                       List<String> args) {
      startMainIsolateFunction((){
        runZoned<void>(() {
          if (userMainFunction is _BinaryFunction) {
            // This seems to be undocumented but supported by the command line VM.
            // Let's do the same in case old entry-points are ported to Flutter.
            (userMainFunction as dynamic)(args, '');
          } else if (userMainFunction is _UnaryFunction) {
            (userMainFunction as dynamic)(args);
          } else {
            userMainFunction();
        }, onError: (Object error, StackTrace stackTrace) {
          _reportUnhandledException(error.toString(), stackTrace.toString());
      }, null);
    复制代码

    _startMainIsolate 函数中就是直接运行 RootIsolate 并执行入口函数。

    @pragma("vm:entry-point", "call")
    void _startIsolate(
        SendPort parentPort,
        Function entryPoint,
        List<String> args,
        var message,
        bool isSpawnUri,
        RawReceivePort controlPort,
        List capabilities) {
      //将所有用户代码处理延迟到消息循环的下一次运行。 这使我们能够拦截事件分发中的某些条件,例如从暂停状态开始。
      RawReceivePort port = new RawReceivePort();
      port.handler = (_) {
        port.close();
        if (isSpawnUri) {
          if (entryPoint is _BinaryFunction) {
            (entryPoint as dynamic)(args, message);
          } else if (entryPoint is _UnaryFunction) {
            (entryPoint as dynamic)(args);
          } else {
            entryPoint();
        } else {
          entryPoint(message);
      //确保消息处理程序已触发。
      port.sendPort.send(null);
    复制代码

    _startIsolate 方法中,就会执行 Flutter 中的入口函数,如下。

    void main() => runApp(MyApp());
    复制代码

    运行 Flutter 代码的流程图如下。

    由于东西比较多,所以本文只是描述了 Engine 的整体创建流程,一些细节也没有具体讲述。但如果熟悉了 Engine 的创建流程,那么也就能很快的去了解细节的具体实现。

    【参考资料】

    深入理解Flutter引擎启动

    分类:
    Android
  •