FlutterEngine引擎初始化

FlutterEngin啓動流程&androidFlutterActivityDelegate初始化UI相關的內容兩篇代碼分析的過程當中,已經分析了加載libflutter.so 的初始化話過程,platform_view_android_jni.cc中調用AttachJNI初始化AndroidShellHolder對象對平臺進行初始化,進行來分析FlutterEngine初始化過程。java

!!! info "Flutter Engine初始化過程"android

* 1.`Platfrom,UI,IO,GUP`線程的管理,配置參數的的加載
* 2.建立一個線程清理虛擬機退出的清理工做
* 3.`thread_host_`負責管理相關的線程,託管四個相處`TaskRunner`,`TaskRunners`
* 4.`PlatformViewAndroid`的建立,負責管理平臺側是事件處理在UI線程執行
* 5.`Rasterizer`的初始化柵格化在GPU線程執行
* 6.`MessageLoop`的建立,在platfrom中運行
* 7.`TaskRunners`管理添加到不一樣平臺中的線程執行,負責管理四個任務運行器
* 8.`Shell`加載第三方庫,Java虛擬機的建立
複製代碼

加載Flutter資源

JNI_OnLoad

Flutter.so中Android端的入口函數engine/src/flutter/shell/platform/android/library_loader.ccios

Java加載Flutter.so庫完成時,開始初始化Flutter引擎c++

1.註冊Flutter層的代碼shell

2.初始化AndroidViewwindows

3.初始化FlutterMain緩存

在Android端初始化Flutter 相關的環境經過兩個步驟來完成:安全

// This is called by the VM when the shared library is first loaded.
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  // Initialize the Java VM.
  fml::jni::InitJavaVM(vm);

  JNIEnv* env = fml::jni::AttachCurrentThread();
  bool result = false;

  // Register FlutterMain.
  result = shell::FlutterMain::Register(env);
  FML_CHECK(result);

  // Register PlatformView
  result = shell::PlatformViewAndroid::Register(env);
  FML_CHECK(result);

  // Register VSyncWaiter.
  result = shell::VsyncWaiterAndroid::Register(env);
  FML_CHECK(result);

  return JNI_VERSION_1_4;
}

複製代碼

FlutterMain::Register(env);

1.轉換FlutterJNI中的nativeInit函數到JNIinit函數而且初始化相關的引擎bash

2.加載FlutterMain中的全部native函數app

開始初始化Register查找Flutter.jar中的Java方法

bool FlutterMain::Register(JNIEnv* env) {
  static const JNINativeMethod methods[] = {
      {
          .name = "nativeInit",
          .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
                       "lang/String;Ljava/lang/String;Ljava/lang/String;)V",
          .fnPtr = reinterpret_cast<void*>(&Init),
      },
      {
          .name = "nativeRecordStartTimestamp",
          .signature = "(J)V",
          .fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
      },
  };

  jclass clazz = env->FindClass("io/flutter/view/FlutterMain");

  if (clazz == nullptr) {
    return false;
  }

  return env->RegisterNatives(clazz, methods, arraysize(methods)) == 0;
}
複製代碼

FlutterMain.cc文件時FlutterEngine和Android平臺相關的入口類,主要處理Android相關的資源文件和初始化FlutterMain.cc

1.在調用Register函數時,已經把FlutterJNI中的nativeInit映射到FlutterMain中的nativeInit,傳入Flutter在Android端的相關文件

2.找到Android引擎啓動時從Apk包中解壓出來的資源文件

3.加載Flutter編譯出來的相關文件kernel_blob

4.初始化FlutterMaing_flutter_main.reset(new FlutterMain(std::move(settings)));

void FlutterMain::Init(JNIEnv* env,
                       jclass clazz,
                       jobject context,
                       jobjectArray jargs,
                       jstring bundlePath,
                       jstring appStoragePath,
                       jstring engineCachesPath) {
  std::vector<std::string> args;
  args.push_back("flutter");
  for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
    args.push_back(std::move(arg));
  }
  auto command_line = fml::CommandLineFromIterators(args.begin(), args.end());

  auto settings = SettingsFromCommandLine(command_line);

  settings.assets_path = fml::jni::JavaStringToString(env, bundlePath);

  // Restore the callback cache.
  // TODO(chinmaygarde): Route all cache file access through FML and remove this
  // setter.
  blink::DartCallbackCache::SetCachePath(
      fml::jni::JavaStringToString(env, appStoragePath));

  fml::paths::InitializeAndroidCachesPath(
      fml::jni::JavaStringToString(env, engineCachesPath));

  blink::DartCallbackCache::LoadCacheFromDisk();

  if (!blink::DartVM::IsRunningPrecompiledCode()) {
    // Check to see if the appropriate kernel files are present and configure
    // settings accordingly.
    auto application_kernel_path =
        fml::paths::JoinPaths({settings.assets_path, "kernel_blob.bin"});

    if (fml::IsFile(application_kernel_path)) {
      settings.application_kernel_asset = application_kernel_path;
    }
  }

  settings.task_observer_add = [](intptr_t key, fml::closure callback) {
    fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
  };

  settings.task_observer_remove = [](intptr_t key) {
    fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
  };

#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
  // There are no ownership concerns here as all mappings are owned by the
  // embedder and not the engine.
  auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
    return [mapping, size]() {
      return std::make_unique<fml::NonOwnedMapping>(mapping, size);
    };
  };

  settings.dart_library_sources_kernel =
      make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG

  // Not thread safe. Will be removed when FlutterMain is refactored to no
  // longer be a singleton.
  g_flutter_main.reset(new FlutterMain(std::move(settings)));
}
複製代碼

倒目前爲止已經加載完成Flutter相關的資源文件,接下來就須要開始初始化View相關的邏輯和Android端通訊

在下圖中:

  • 1.初始化Flutter Engine 運行FlutterUI庫的環境,初始化AndroidShellHolder:來管理Flutter相關的引環境
  • 2.PlatformViewAndroid在JNI層進行View的繪製和事件處理,註冊SurfaceView給Flutter Eingine,提供給引擎進行繪製的畫布,調用ANative_window類來鏈接FlutterUI和AndroidUI的橋樑

PlatformViewAndroid

JNI調用的綁定關係

初始化Android平臺相關的View邏輯,綁定Flutter.jar類和Android 繪圖引擎的初始化綁定工做,初始化工做主要的內容是在註冊相關的Java層的本地方法到JNI層,創建好C++和Java層相互調用函數關係

1.io/flutter/view/FlutterCallbackInformation

2.io/flutter/embedding/engine/FlutterJNI

3.android/graphics/SurfaceTexture

4.attachToGLContext

5.updateTexImage

6.getTransformMatrix

7.detachFromGLContext

bool PlatformViewAndroid::Register(JNIEnv* env) {
  if (env == nullptr) {
    FML_LOG(ERROR) << "No JNIEnv provided";
    return false;
  }

  g_flutter_callback_info_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
      env, env->FindClass("io/flutter/view/FlutterCallbackInformation"));
  if (g_flutter_callback_info_class->is_null()) {
    FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation class";
    return false;
  }

  g_flutter_callback_info_constructor = env->GetMethodID(
      g_flutter_callback_info_class->obj(), "<init>",
      "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  if (g_flutter_callback_info_constructor == nullptr) {
    FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation constructor";
    return false;
  }

  g_flutter_jni_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
      env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
  if (g_flutter_jni_class->is_null()) {
    FML_LOG(ERROR) << "Failed to find FlutterJNI Class.";
    return false;
  }

  g_surface_texture_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
      env, env->FindClass("android/graphics/SurfaceTexture"));
  if (g_surface_texture_class->is_null()) {
    FML_LOG(ERROR) << "Could not locate SurfaceTexture class";
    return false;
  }

  static const JNINativeMethod callback_info_methods[] = {
      {
          .name = "nativeLookupCallbackInformation",
          .signature = "(J)Lio/flutter/view/FlutterCallbackInformation;",
          .fnPtr = reinterpret_cast<void*>(&shell::LookupCallbackInformation),
      },
  };

  if (env->RegisterNatives(g_flutter_callback_info_class->obj(),
                           callback_info_methods,
                           arraysize(callback_info_methods)) != 0) {
    FML_LOG(ERROR) << "Failed to RegisterNatives with FlutterCallbackInfo";
    return false;
  }

  g_attach_to_gl_context_method = env->GetMethodID(
      g_surface_texture_class->obj(), "attachToGLContext", "(I)V");

  if (g_attach_to_gl_context_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate attachToGlContext method";
    return false;
  }

  g_update_tex_image_method =
      env->GetMethodID(g_surface_texture_class->obj(), "updateTexImage", "()V");

  if (g_update_tex_image_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate updateTexImage method";
    return false;
  }

  g_get_transform_matrix_method = env->GetMethodID(
      g_surface_texture_class->obj(), "getTransformMatrix", "([F)V");

  if (g_get_transform_matrix_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate getTransformMatrix method";
    return false;
  }

  g_detach_from_gl_context_method = env->GetMethodID(
      g_surface_texture_class->obj(), "detachFromGLContext", "()V");

  if (g_detach_from_gl_context_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate detachFromGlContext method";
    return false;
  }

  return RegisterApi(env);
}

}  // namespace shell

複製代碼

註冊Android端和View操做相關的邏輯,初始化FlutterView本身的環境

FlutterJNI

1.AttachJNI
  2.DestroyJNI
  3.AssetManager
複製代碼
bool RegisterApi(JNIEnv* env) {
  static const JNINativeMethod flutter_jni_methods[] = {
      // Start of methods from FlutterNativeView
      {
          .name = "nativeAttach",
          .signature = "(Lio/flutter/embedding/engine/FlutterJNI;Z)J",
          .fnPtr = reinterpret_cast<void*>(&shell::AttachJNI),
      },
      {
          .name = "nativeDestroy",
          .signature = "(J)V",
          .fnPtr = reinterpret_cast<void*>(&shell::DestroyJNI),
      },
      {
          .name = "nativeRunBundleAndSnapshotFromLibrary",
          .signature = "(J[Ljava/lang/String;Ljava/lang/String;"
                       "Ljava/lang/String;Landroid/content/res/AssetManager;)V",
          .fnPtr =
              reinterpret_cast<void*>(&shell::RunBundleAndSnapshotFromLibrary),
      },
      {
          .name = "nativeGetObservatoryUri",
          .signature = "()Ljava/lang/String;",
          .fnPtr = reinterpret_cast<void*>(&shell::GetObservatoryUri),
      },
      {
          .name = "nativeDispatchEmptyPlatformMessage",
          .signature = "(JLjava/lang/String;I)V",
          .fnPtr =
              reinterpret_cast<void*>(&shell::DispatchEmptyPlatformMessage),
      },
      {
          .name = "nativeDispatchPlatformMessage",
          .signature = "(JLjava/lang/String;Ljava/nio/ByteBuffer;II)V",
          .fnPtr = reinterpret_cast<void*>(&shell::DispatchPlatformMessage),
      },
      {
          .name = "nativeInvokePlatformMessageResponseCallback",
          .signature = "(JILjava/nio/ByteBuffer;I)V",
          .fnPtr = reinterpret_cast<void*>(
              &shell::InvokePlatformMessageResponseCallback),
      },
      {
          .name = "nativeInvokePlatformMessageEmptyResponseCallback",
          .signature = "(JI)V",
          .fnPtr = reinterpret_cast<void*>(
              &shell::InvokePlatformMessageEmptyResponseCallback),
      },

      // Start of methods from FlutterView
      {
          .name = "nativeGetBitmap",
          .signature = "(J)Landroid/graphics/Bitmap;",
          .fnPtr = reinterpret_cast<void*>(&shell::GetBitmap),
      },
      {
          .name = "nativeSurfaceCreated",
          .signature = "(JLandroid/view/Surface;)V",
          .fnPtr = reinterpret_cast<void*>(&shell::SurfaceCreated),
      },
      {
          .name = "nativeSurfaceChanged",
          .signature = "(JII)V",
          .fnPtr = reinterpret_cast<void*>(&shell::SurfaceChanged),
      },
      {
          .name = "nativeSurfaceDestroyed",
          .signature = "(J)V",
          .fnPtr = reinterpret_cast<void*>(&shell::SurfaceDestroyed),
      },
      {
          .name = "nativeSetViewportMetrics",
          .signature = "(JFIIIIIIIIII)V",
          .fnPtr = reinterpret_cast<void*>(&shell::SetViewportMetrics),
      },
      {
          .name = "nativeDispatchPointerDataPacket",
          .signature = "(JLjava/nio/ByteBuffer;I)V",
          .fnPtr = reinterpret_cast<void*>(&shell::DispatchPointerDataPacket),
      },
      {
          .name = "nativeDispatchSemanticsAction",
          .signature = "(JIILjava/nio/ByteBuffer;I)V",
          .fnPtr = reinterpret_cast<void*>(&shell::DispatchSemanticsAction),
      },
      {
          .name = "nativeSetSemanticsEnabled",
          .signature = "(JZ)V",
          .fnPtr = reinterpret_cast<void*>(&shell::SetSemanticsEnabled),
      },
      {
          .name = "nativeSetAccessibilityFeatures",
          .signature = "(JI)V",
          .fnPtr = reinterpret_cast<void*>(&shell::SetAccessibilityFeatures),
      },
      {
          .name = "nativeGetIsSoftwareRenderingEnabled",
          .signature = "()Z",
          .fnPtr = reinterpret_cast<void*>(&shell::GetIsSoftwareRendering),
      },
      {
          .name = "nativeRegisterTexture",
          .signature = "(JJLandroid/graphics/SurfaceTexture;)V",
          .fnPtr = reinterpret_cast<void*>(&shell::RegisterTexture),
      },
      {
          .name = "nativeMarkTextureFrameAvailable",
          .signature = "(JJ)V",
          .fnPtr = reinterpret_cast<void*>(&shell::MarkTextureFrameAvailable),
      },
      {
          .name = "nativeUnregisterTexture",
          .signature = "(JJ)V",
          .fnPtr = reinterpret_cast<void*>(&shell::UnregisterTexture),
      },
  };

  if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
                           arraysize(flutter_jni_methods)) != 0) {
    FML_LOG(ERROR) << "Failed to RegisterNatives with FlutterJNI";
    return false;
  }

  g_handle_platform_message_method =
      env->GetMethodID(g_flutter_jni_class->obj(), "handlePlatformMessage",
                       "(Ljava/lang/String;[BI)V");

  if (g_handle_platform_message_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate handlePlatformMessage method";
    return false;
  }

  g_handle_platform_message_response_method = env->GetMethodID(
      g_flutter_jni_class->obj(), "handlePlatformMessageResponse", "(I[B)V");

  if (g_handle_platform_message_response_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate handlePlatformMessageResponse method";
    return false;
  }

  g_update_semantics_method =
      env->GetMethodID(g_flutter_jni_class->obj(), "updateSemantics",
                       "(Ljava/nio/ByteBuffer;[Ljava/lang/String;)V");

  if (g_update_semantics_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate updateSemantics method";
    return false;
  }

  g_update_custom_accessibility_actions_method = env->GetMethodID(
      g_flutter_jni_class->obj(), "updateCustomAccessibilityActions",
      "(Ljava/nio/ByteBuffer;[Ljava/lang/String;)V");

  if (g_update_custom_accessibility_actions_method == nullptr) {
    FML_LOG(ERROR)
        << "Could not locate updateCustomAccessibilityActions method";
    return false;
  }

  g_on_first_frame_method =
      env->GetMethodID(g_flutter_jni_class->obj(), "onFirstFrame", "()V");

  if (g_on_first_frame_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate onFirstFrame method";
    return false;
  }

  g_on_engine_restart_method =
      env->GetMethodID(g_flutter_jni_class->obj(), "onPreEngineRestart", "()V");

  if (g_on_engine_restart_method == nullptr) {
    FML_LOG(ERROR) << "Could not locate onEngineRestart method";
    return false;
  }

  return true;
}
複製代碼

FlutterView 初始化

FlutterNativeView初始化時註冊Android PluginMessage到JNI中

public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
        this.flutterUiDisplayListener = new FlutterUiDisplayListener() {
            public void onFlutterUiDisplayed() {
                if (FlutterNativeView.this.mFlutterView != null) {
                    FlutterNativeView.this.mFlutterView.onFirstFrame();
                }
            }

            public void onFlutterUiNoLongerDisplayed() {
            }
        };
        this.mContext = context;
        this.mPluginRegistry = new FlutterPluginRegistry(this, context);
        this.mFlutterJNI = new FlutterJNI();
        this.mFlutterJNI.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener);
        this.dartExecutor = new DartExecutor(this.mFlutterJNI, context.getAssets());
        this.mFlutterJNI.addEngineLifecycleListener(new FlutterNativeView.EngineLifecycleListenerImpl());
        this.attach(this, isBackgroundView);
        this.assertAttached();
    }
複製代碼

FlutterNativeView

public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
    this.flutterUiDisplayListener = new FlutterUiDisplayListener() {
        public void onFlutterUiDisplayed() {
            if (FlutterNativeView.this.mFlutterView != null) {
                FlutterNativeView.this.mFlutterView.onFirstFrame();
            }
        }

        public void onFlutterUiNoLongerDisplayed() {
        }
    };
    this.mContext = context;
    this.mPluginRegistry = new FlutterPluginRegistry(this, context);
    this.mFlutterJNI = new FlutterJNI();
    this.mFlutterJNI.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener);
    this.dartExecutor = new DartExecutor(this.mFlutterJNI, context.getAssets());
    this.mFlutterJNI.addEngineLifecycleListener(new FlutterNativeView.EngineLifecycleListenerImpl());
    初始化JIN
    this.attach(this, isBackgroundView);
    this.assertAttached();
}
複製代碼

AttachJNI

接下來進行分析在JNI層的調用過程:AttachJNI中調用std::make_unique<AndroidShellHolder>方法建立AndroidShellHolder實例engine/src/flutter/shell/platform/android/platform_view_android_jni.cc

// Called By Java
    // 方法註冊進入JNI
    static jlong AttachJNI(JNIEnv* env, jclass clazz, jobject flutterJNI, jboolean is_background_view) {
      fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
      auto shell_holder = std::make_unique<AndroidShellHolder>(
          FlutterMain::Get().GetSettings(), java_object, is_background_view);
      if (shell_holder->IsValid()) {
        return reinterpret_cast<jlong>(shell_holder.release());
      } else {
        return 0;
      }
    }
複製代碼

AndroidShellHolder類是對Platfrom層調用JNI的接口做爲一個代理對象來進行統一的代理入口,使用C++11的智能指針對象來統一管理一個對象C++智能指針

AndroidShellHolder

FlutterEngine的初始化入口

AndroidShellHolder:主要是管理flutter engine 在Platform端的入口:

  • 1.Platfrom,UI,IO,GUP線程的管理,配置參數的的加載
  • 2.建立一個線程清理虛擬機退出的清理工做
  • 3.thread_host_負責管理相關的線程,託管四個相處
  • 4.PlatformViewAndroid的建立,負責管理平臺側是事件處理在UI線程執行
  • 5.Rasterizer的初始化柵格化在GPU線程執行
  • 6.MessageLoop的建立,在platfrom中運行
  • 7.TaskRunners管理添加到不一樣平臺中的線程執行,負責管理四個任務運行器
  • 8.Shell加載第三方庫,Java虛擬機的建立

// 參數說明:
//
// blink::Settings settings,//配置數據
// fml::jni::JavaObjectWeakGlobalRef java_object,//FlutterJNI 對象
// bool is_background_view
// static size_t shell_count = 1; Shell:對象的個數爲一個
// 完成:
// 1.加載Settings配置文件,綁定全局對象java_object
// 2.建立一個線程清理虛擬機退出的清理工做
// 3.ThreadHost類來管理Flutter engine的Platform,io,GPU,UI線程
// 4.初始化消息隊列:fml::MessageLoop::EnsureInitializedForCurrentThread();
    //FlutterEngine的初始化入口
AndroidShellHolder::AndroidShellHolder(
    blink::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++);
  // 建立一個線程清理虛擬機退出的清理工做
  FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) ==
            0);

  if (is_background_view) {
    thread_host_ = {thread_label, ThreadHost::Type::UI};
  } else {
    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;
        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.GetTaskRunners());
  };

  // The current thread will be used as the platform thread. Ensure that the
  // message loop is initialized.
  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();
  }
  blink::TaskRunners task_runners(thread_label, // label platform_runner, // platform gpu_runner, // gpu ui_runner, // ui io_runner // io );

  shell_ =
      Shell::Create(task_runners,             // task runners
                    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_) {
    task_runners.GetGPUTaskRunner()->PostTask([]() {
      // Android describes -8 as "most important display threads, for
      // compositing the screen and retrieving input events". Conservatively
      // set the GPU thread to slightly lower priority than it.
      if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
        // Defensive fallback. Depending on the OEM, it may not be possible
        // to set priority to -5.
        if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
          FML_LOG(ERROR) << "Failed to set GPU task runner priority";
        }
      }
    });
    task_runners.GetUITaskRunner()->PostTask([]() {
      if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
        FML_LOG(ERROR) << "Failed to set UI task runner priority";
      }
    });
  }
}
複製代碼

建立一個線程處理JNI退出任務

建立一個線程來對DartVM虛擬機退出後作一塊兒掃尾工做,而且添加到ui_thread,若是is_background_view(該參數是在FlutterJNI調用是傳入)是在後臺工做,也添加到GPU_Thread裏面

// 建立一個線程清理虛擬機退出的清理工做
FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) == 0);
複製代碼
// 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);
}
複製代碼

Flutter Engine線程池模式

Flutter Engine要求Embeder提供四個Task Runner,Embeder指的是將引擎移植到平臺的中間層代碼。這四個主要的Task Runner包括:

flutterThread.jpeg

根據在java層調用native層的調用是傳入的參數判斷建立線程的類型:

  • 1.建立一個ThreadHost來管理4個線程對象
  • 2.定義一個線程類的代理類/engine/src/flutter/fml/thread.cc
  • 3.在線程代理類中建立MessageLoop、綁定TaskRunner,同時啓動MessageLoop
  • 4.建立一個TaskRunners類來管理四個任務運行器

ThreadHost

if (is_background_view) {
  thread_host_ = {thread_label, ThreadHost::Type::UI};
} else {
  thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
                                    ThreadHost::Type::IO};
}
複製代碼

ThreadHost 類主要是建立的Platform,UI,IO,GPU線程,主要用來對四個線程的宿主對象,定義一個枚舉類型來標記四種線程的類型:

enum Type {
  Platform = 1 << 0,
  UI = 1 << 1,
  GPU = 1 << 2,
  IO = 1 << 3,
};
複製代碼

構造方法建立四個線程C++智能指針:

ThreadHost::ThreadHost(std::string name_prefix, uint64_t mask) {
  if (mask & ThreadHost::Type::Platform) {
    platform_thread = std::make_unique<fml::Thread>(name_prefix + ".platform");
  }

  if (mask & ThreadHost::Type::UI) {
    ui_thread = std::make_unique<fml::Thread>(name_prefix + ".ui");
  }

  if (mask & ThreadHost::Type::GPU) {
    gpu_thread = std::make_unique<fml::Thread>(name_prefix + ".gpu");
  }

  if (mask & ThreadHost::Type::IO) {
    io_thread = std::make_unique<fml::Thread>(name_prefix + ".io");
  }
}
複製代碼

MessageLoop

在engine/src/flutter/fml/thread.cc構造方法中建立線程類,同時初始化MessageLoop,關聯任務運行器到消息隊列,同時啓動消息隊列loop.Run(),是個線程建立的時候分別建立了四個不一樣的MessageLoop

Thread::Thread(const std::string& name) : joined_(false) {
  fml::AutoResetWaitableEvent latch;
  fml::RefPtr<fml::TaskRunner> runner;
  thread_ = std::make_unique<std::thread>([&latch, &runner, name]() -> void {
    SetCurrentThreadName(name);
    fml::MessageLoop::EnsureInitializedForCurrentThread();//初始化消息隊列
    auto& loop = MessageLoop::GetCurrent();
    runner = loop.GetTaskRunner();
    latch.Signal();
    loop.Run();//啓動消息隊列
  });
  // 當前線程等待狀態
  latch.Wait();
  task_runner_ = runner;
}
複製代碼

Platform Task Runner:

Flutter Engine的主Task Runner,相似於Android Main Thread或者iOS的Main Thread。可是須要注意他們仍是有區別的。

通常來講,一個Flutter應用啓動的時候會建立一個Engine實例,Engine建立的時候會建立一個線程供Platform Runner使用。

跟Flutter Engine的全部交互(接口調用)必須在Platform Thread進行,不然可能致使沒法預期的異常。這跟iOS UI相關的操做都必須在主線程進行相相似。須要注意的是在Flutter Engine中有不少模塊都是非線程安全的。

規則很簡單,對於Flutter Engine的接口調用都需保證在Platform Thread進行。

阻塞Platform Thread不會直接致使Flutter應用的卡頓(跟iOS android主線程不一樣)。儘管如此,也不建議在這個Runner執行繁重的操做,長時間卡住Platform Thread應用有可能會被系統Watchdog強殺。

UI Task Runner Thread(Dart Runner)

UI Task Runner用於執行Dart root isolate代碼(isolate咱們後面會講到,姑且先簡單理解爲Dart VM裏面的線程)。Root isolate比較特殊,它綁定了很多Flutter須要的函數方法,以便進行渲染相關操做。對於每一幀,引擎要作的事情有:

Root isolate通知Flutter Engine有幀須要渲染。 Flutter Engine通知平臺,須要在下一個vsync的時候獲得通知。 平臺等待下一個vsync 對建立的對象和Widgets進行Layout並生成一個Layer Tree,這個Tree立刻被提交給Flutter Engine。當前階段沒有進行任何光柵化,這個步驟僅是生成了對須要繪製內容的描述。 建立或者更新Tree,這個Tree包含了用於屏幕上顯示Widgets的語義信息。這個東西主要用於平臺相關的輔助Accessibility元素的配置和渲染。 除了渲染相關邏輯以外Root Isolate仍是處理來自Native Plugins的消息,Timers,Microtasks和異步IO等操做。Root Isolate負責建立管理的Layer Tree最終決定繪製到屏幕上的內容。所以這個線程的過載會直接致使卡頓掉幀。

GPU Task Runner

GPU Task Runner主要用於執行設備GPU的指令。UI Task Runner建立的Layer Tree是跨平臺的,它不關心到底由誰來完成繪製。GPU Task Runner負責將Layer Tree提供的信息轉化爲平臺可執行的GPU指令。GPU Task Runner同時負責繪製所須要的GPU資源的管理。資源主要包括平臺Framebuffer,Surface,Texture和Buffers等。

通常來講UI Runner和GPU Runner跑在不一樣的線程。GPU Runner會根據目前幀執行的進度去向UI Runner要求下一幀的數據,在任務繁重的時候可能會告訴UI Runner延遲任務。這種調度機制確保GPU Runner不至於過載,同時也避免了UI Runner沒必要要的消耗。

建議爲每個Engine實例都新建一個專用的GPU Runner線程。

IO Task Runner

前面討論的幾個Runner對於執行流暢度有比較高的要求。Platform Runner過載可能致使系統WatchDog強殺,UI和GPU Runner過載則可能致使Flutter應用的卡頓。可是GPU線程的一些必要操做,例如IO,放到哪裏執行呢?答案正是IO Runner。

IO Runner的主要功能是從圖片存儲(好比磁盤)中讀取壓縮的圖片格式,將圖片數據進行處理爲GPU Runner的渲染作好準備。IO Runner首先要讀取壓縮的圖片二進制數據(好比PNG,JPEG),將其解壓轉換成GPU可以處理的格式而後將數據上傳到GPU。

獲取諸如ui.Image這樣的資源只有經過async call去調用,當調用發生的時候Flutter Framework告訴IO Runner進行加載的異步操做。

IO Runner直接決定了圖片和其它一些資源加載的延遲間接影響性能。因此建議爲IO Runner建立一個專用的線程。

TaskRunner

ThreadHost建立完成四個線程以後,在建立四個TaskRunner來管理Platform,UI,GPU,IO線程中的任務engine/src/flutter/fml/task_runner.h

提供四個方法處理提交到MessageLoop的任務的執行時間和關聯到消息隊列

  • PostTask
  • PostTaskForTime
  • PostDelayedTask
  • RunNowOrPostTask
  • RefPtr loop_
namespace fml {

class MessageLoopImpl;

class TaskRunner : public fml::RefCountedThreadSafe<TaskRunner> {
 public:
  virtual void PostTask(fml::closure task);

  virtual void PostTaskForTime(fml::closure task, fml::TimePoint target_time);

  virtual void PostDelayedTask(fml::closure task, fml::TimeDelta delay);

  virtual bool RunsTasksOnCurrentThread();

  virtual ~TaskRunner();

  static void RunNowOrPostTask(fml::RefPtr<fml::TaskRunner> runner, fml::closure task);

 protected:
  TaskRunner(fml::RefPtr<MessageLoopImpl> loop);

 private:
  fml::RefPtr<MessageLoopImpl> loop_;

  FML_FRIEND_MAKE_REF_COUNTED(TaskRunner);
  FML_FRIEND_REF_COUNTED_THREAD_SAFE(TaskRunner);
  FML_DISALLOW_COPY_AND_ASSIGN(TaskRunner);
};

}  // namespace fml

#endif // FLUTTER_FML_TASK_RUNNER_H_
複製代碼

TaskRunners

建立一個TaskRunners統一管理四個線程中的任務

TaskRunners task_runners(thread_label, // label platform_runner, // platform gpu_runner, // gpu ui_runner, // ui io_runner // io 複製代碼
namespace blink {

記錄平臺相關的四個相關的線程的任務統一的管理。
class TaskRunners {
 public:
  TaskRunners(std::string label,
              fml::RefPtr<fml::TaskRunner> platform, //平臺線程關聯
              fml::RefPtr<fml::TaskRunner> gpu,//gpu線程關聯
              fml::RefPtr<fml::TaskRunner> ui,//ui相處的關聯
              fml::RefPtr<fml::TaskRunner> io);//io相處
........
 private:
  const std::string label_;
  fml::RefPtr<fml::TaskRunner> platform_;
  fml::RefPtr<fml::TaskRunner> gpu_;
  fml::RefPtr<fml::TaskRunner> ui_;
  fml::RefPtr<fml::TaskRunner> io_;
};

}  // namespace blink

#endif // FLUTTER_COMMON_TASK_RUNNERS_H_
複製代碼

Shell類初始化:

Shell 類的初始化,主要負責管理客戶端相關的資源/engine/src/flutter/shell/platform/android/android_shell_holder.cc,建立的地方

!!! info "Shell主要的功能初始化如下四個對象"

* platform_view_ = std::move(platform_view);
* engine_ = std::move(engine);
* rasterizer_ = std::move(rasterizer);
* io_manager_ = std::move(io_manager);
* 建立DartVM虛擬機
複製代碼

主要執行的動做:

!!! waring "在new Shell時候有重新建立了一個DartVM"

  • 1.記錄開始時間
  • 2.初始化日誌設置
  • 3.初始化Skia:InitSkiaEventTracer
  • 4.初始化:SkGraphics
  • 5.初始化本地化庫:InitializeICU
  • 6.建立虛擬機:blink::DartVM::ForProcess(settings);
  • 7.開啓平臺任務任務
  • new Shell
  • 7.2:在new Shell時候有重新建立了一個DartVM:
  • 7.3 Install service protocol handlers.
  • 8.真正建立平臺操做的對象/engine/src/flutter/shell/platform/android/platform_view_android.cc
  • 9.建立一個CreateVSyncWaiter對象
  • 10.建立IOManager管理器,在IO線程執行
  • 11.建立Rasterizer執行在GPU線程
  • 12.建立engine在UI線程執行
Shell::Shell(blink::TaskRunners task_runners, blink::Settings settings)
: task_runners_(std::move(task_runners)),//任務運行器
settings_(std::move(settings)),
vm_(blink::DartVM::ForProcess(settings_)) {//建立一個新的DartVM
FML_DCHECK(task_runners_.IsValid());
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
複製代碼
shell_ =
    Shell::Create(task_runners,             // task runners
                  settings_,                // settings
                  on_create_platform_view,  // platform view create callback
                  on_create_rasterizer      // rasterizer create callback
    );

在Shell建立時:

  std::unique_ptr<Shell> Shell::Create(
      blink::TaskRunners task_runners,
      blink::Settings settings,
      Shell::CreateCallback<PlatformView> on_create_platform_view,
      Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
    //初始化第三方庫
    PerformInitializationTasks(settings);

    //初始化DartVM虛擬機
    auto vm = blink::DartVM::ForProcess(settings);
    FML_CHECK(vm) << "Must be able to initialize the VM.";
    return Shell::Create(std::move(task_runners),             //
                         std::move(settings),                 //
                         vm->GetIsolateSnapshot(),            //
                         blink::DartSnapshot::Empty(),        //
                         std::move(on_create_platform_view),  //
                         std::move(on_create_rasterizer)      //
    );
  }

複製代碼

初始化DartVM

DartVM::ForProcess

Dart VM 虛擬機在Shell建立的時候初始化:auto vm = blink::DartVM::ForProcess(settings);,/engine/src/flutter/shell/common/shell.cc,Shell::Create,Dart虛擬機的分析,在後續在進行擴展

  • 1.加載dart虛擬機快照
  • 2.加載Isolate快照
  • 3.調用DartVM構造方法初始化虛擬機
fml::RefPtr<DartVM> DartVM::ForProcess(
    Settings settings,
    fml::RefPtr<DartSnapshot> vm_snapshot,
    fml::RefPtr<DartSnapshot> isolate_snapshot,
    fml::RefPtr<DartSnapshot> shared_snapshot) {
  std::lock_guard<std::mutex> lock(gVMMutex);
  std::call_once(gVMInitialization, [settings,          //
                                     vm_snapshot,       //
                                     isolate_snapshot,  //
                                     shared_snapshot    //
  ]() mutable {
    if (!vm_snapshot) {
      vm_snapshot = DartSnapshot::VMSnapshotFromSettings(settings);
    }
    if (!(vm_snapshot && vm_snapshot->IsValid())) {
      FML_LOG(ERROR) << "VM snapshot must be valid.";
      return;
    }
    if (!isolate_snapshot) {
      isolate_snapshot = DartSnapshot::IsolateSnapshotFromSettings(settings);
    }
    if (!(isolate_snapshot && isolate_snapshot->IsValid())) {
      FML_LOG(ERROR) << "Isolate snapshot must be valid.";
      return;
    }
    if (!shared_snapshot) {
      shared_snapshot = DartSnapshot::Empty();
    }
    gVM = fml::MakeRefCounted<DartVM>(settings,                     //
                                      std::move(vm_snapshot),       //
                                      std::move(isolate_snapshot),  //
                                      std::move(shared_snapshot)    //
    );
  });
  return gVM;
  }

複製代碼

Shell建立時第三方庫初始化位置

PerformInitializationTasks,/engine/src/flutter/shell/common/shell.cc

  • RecordStartupTimestamp()記錄時間戳
  • fml::SetLogSettings(log_settings) 設置日誌信息
  • InitSkiaEventTracer(settings.trace_skia) 初始化Skia2d圖像引擎庫跟蹤器
  • SkGraphics::Init();  初始化2d圖形引擎庫
  • fml::icu::InitializeICU(settings.icu_data_path); 初始化國際化處理ICU
// Though there can be multiple shells, some settings apply to all components in
// the process. These have to be setup before the shell or any of its
// sub-components can be initialized. In a perfect world, this would be empty.
// TODO(chinmaygarde): The unfortunate side effect of this call is that settings
// that cause shell initialization failures will still lead to some of their
// settings being applied.
static void PerformInitializationTasks(const blink::Settings& settings) {
  static std::once_flag gShellSettingsInitialization = {};
  std::call_once(gShellSettingsInitialization, [&settings] {
    RecordStartupTimestamp();

    {
      fml::LogSettings log_settings;
      log_settings.min_log_level =
          settings.verbose_logging ? fml::LOG_INFO : fml::LOG_ERROR;
      fml::SetLogSettings(log_settings);
    }

    tonic::SetLogHandler(
        [](const char* message) { FML_LOG(ERROR) << message; });

    if (settings.trace_skia) {
      InitSkiaEventTracer(settings.trace_skia);
    }

    if (!settings.skia_deterministic_rendering_on_cpu) {
      SkGraphics::Init();
    } else {
      FML_DLOG(INFO) << "Skia deterministic rendering is enabled.";
    }

    if (settings.icu_initialization_required) {
      if (settings.icu_data_path.size() != 0) {
        fml::icu::InitializeICU(settings.icu_data_path);
      } else if (settings.icu_mapper) {
        fml::icu::InitializeICUFromMapping(settings.icu_mapper());
      } else {
        FML_DLOG(WARNING) << "Skipping ICU initialization in the shell.";
      }
    }
  });
}
複製代碼

CreateShellOnPlatformThread

Shell建立所須要的在這個類裏面進行初始化CreateShellOnPlatformThread對Shell對應的platefrom,IO,GPU,UI,/engine/src/flutter/shell/common/shell.cc,如下的類主要觀察構造方法中傳入的參數,可以幫助理解相關的邏輯調用 !!! WARNING "如下代碼片斷是真正初始化對象的地方"

std::unique_ptr<Shell> Shell::Create(
    blink::TaskRunners task_runners,
    blink::Settings settings,
    fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
    fml::RefPtr<blink::DartSnapshot> shared_snapshot,
    Shell::CreateCallback<PlatformView> on_create_platform_view,
    Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
  PerformInitializationTasks(settings);

  if (!task_runners.IsValid() || !on_create_platform_view ||
      !on_create_rasterizer) {
    return nullptr;
  }

  fml::AutoResetWaitableEvent latch;
  std::unique_ptr<Shell> shell;
  fml::TaskRunner::RunNowOrPostTask(//提交任務到Platform線程運行
      task_runners.GetPlatformTaskRunner(),
      [&latch,                                          //
       &shell,                                          //
       task_runners = std::move(task_runners),          //
       settings,                                        //
       isolate_snapshot = std::move(isolate_snapshot),  //
       shared_snapshot = std::move(shared_snapshot),    //
       on_create_platform_view,                         //
       on_create_rasterizer                             //
  ]() {
        shell = CreateShellOnPlatformThread(std::move(task_runners),      //
                                            settings,                     //
                                            std::move(isolate_snapshot),  //
                                            std::move(shared_snapshot),   //
                                            on_create_platform_view,      //
                                            on_create_rasterizer          //
        );
        latch.Signal();
      });
  latch.Wait();
  return shell;
}
複製代碼

CreateShellOnPlatformThread`完成Shell分的一下初始化信息

  • 1.建立一個Shell實例對象`auto shell = std::unique_ptr(new Shell(task_runners, settings));
  • 2.建立平臺View在平臺線程`auto platform_view = on_create_platform_view(*shell.get());
  • 3.建立一個Syncwaiter`auto vsync_waiter = platform_view->CreateVSyncWaiter();
  • 4.建立一個IO管理io線程`std::unique_ptr io_manager;
  • 5.在UI線程建立engine:`fml::AutoResetWaitableEvent ui_latch;
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
  blink::TaskRunners task_runners,
  blink::Settings settings,
  fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
  fml::RefPtr<blink::DartSnapshot> shared_snapshot,
  Shell::CreateCallback<PlatformView> on_create_platform_view,
  Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
if (!task_runners.IsValid()) {
  return nullptr;
}

auto shell = std::unique_ptr<Shell>(new Shell(task_runners, settings));

// Create the platform view on the platform thread (this thread).
auto platform_view = on_create_platform_view(*shell.get());
if (!platform_view || !platform_view->GetWeakPtr()) {
  return nullptr;
}

// Ask the platform view for the vsync waiter. This will be used by the engine
// to create the animator.
auto vsync_waiter = platform_view->CreateVSyncWaiter();
if (!vsync_waiter) {
  return nullptr;
}

// Create the IO manager on the IO thread. The IO manager must be initialized
// first because it has state that the other subsystems depend on. It must
// first be booted and the necessary references obtained to initialize the
// other subsystems.
fml::AutoResetWaitableEvent io_latch;
std::unique_ptr<IOManager> io_manager;
auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
fml::TaskRunner::RunNowOrPostTask(
    io_task_runner,
    [&io_latch,       //
     &io_manager,     //
     &platform_view,  //
     io_task_runner   //
]() {
      io_manager = std::make_unique<IOManager>(
          platform_view->CreateResourceContext(), io_task_runner);
      io_latch.Signal();
    });
io_latch.Wait();

// Create the rasterizer on the GPU thread.
fml::AutoResetWaitableEvent gpu_latch;
std::unique_ptr<Rasterizer> rasterizer;
fml::WeakPtr<blink::SnapshotDelegate> snapshot_delegate;
fml::TaskRunner::RunNowOrPostTask(
    task_runners.GetGPUTaskRunner(), [&gpu_latch,            //
                                      &rasterizer,           //
                                      on_create_rasterizer,  //
                                      shell = shell.get(),   //
                                      &snapshot_delegate     //
]() {
      if (auto new_rasterizer = on_create_rasterizer(*shell)) {
        rasterizer = std::move(new_rasterizer);
        snapshot_delegate = rasterizer->GetSnapshotDelegate();
      }
      gpu_latch.Signal();
    });

gpu_latch.Wait();

// Create the engine on the UI thread.
fml::AutoResetWaitableEvent ui_latch;
std::unique_ptr<Engine> engine;
fml::TaskRunner::RunNowOrPostTask(
    shell->GetTaskRunners().GetUITaskRunner(),
    fml::MakeCopyable([&ui_latch,                                         //
                       &engine,                                           //
                       shell = shell.get(),                               //
                       isolate_snapshot = std::move(isolate_snapshot),    //
                       shared_snapshot = std::move(shared_snapshot),      //
                       vsync_waiter = std::move(vsync_waiter),            //
                       snapshot_delegate = std::move(snapshot_delegate),  //
                       io_manager = io_manager->GetWeakPtr()              //
]() mutable {
      const auto& task_runners = shell->GetTaskRunners();

      // The animator is owned by the UI thread but it gets its vsync pulses
      // from the platform.
      auto animator = std::make_unique<Animator>(*shell, task_runners,
                                                 std::move(vsync_waiter));

      engine = std::make_unique<Engine>(*shell,                        //
                                        shell->GetDartVM(),            //
                                        std::move(isolate_snapshot),   //
                                        std::move(shared_snapshot),    //
                                        task_runners,                  //
                                        shell->GetSettings(),          //
                                        std::move(animator),           //
                                        std::move(snapshot_delegate),  //
                                        std::move(io_manager)          //
      );
      ui_latch.Signal();
    }));

ui_latch.Wait();
// We are already on the platform thread. So there is no platform latch to
// wait on.

if (!shell->Setup(std::move(platform_view),  //
                  std::move(engine),         //
                  std::move(rasterizer),     //
                  std::move(io_manager))     //
) {
  return nullptr;
}

return shell;
}

複製代碼

設置Shell管理的Platform線程管理的相關資源:/engine/src/flutter/shell/common/engine.cc/engine/src/flutter/shell/common/shell.cc中執行CreateShellOnPlatformThread方法時調用

  • 1.PlatformView:主要管理相關的view事件
  • 2.Engine:全部的資源都準備完成,開始調用dart代碼和Dart虛擬機,進行代碼執行
  • 3.Rasterizer:光柵主要是處理GPU相關的事件
  • 4.IOManager:對io線程進行管理
  • 5.設置 DartVM ServiceProtocol設置處理回調
  • 6.PersistentCache::GetCacheForProcess()->AddWorkerTaskRunner(task_runners_.GetIOTaskRunner());對緩存目錄的處理
bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
                  std::unique_ptr<Engine> engine,
                  std::unique_ptr<Rasterizer> rasterizer,
                  std::unique_ptr<IOManager> io_manager) {
  if (is_setup_) {
    return false;
  }

  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);

  is_setup_ = true;

  if (auto vm = blink::DartVM::ForProcessIfInitialized()) {
    vm->GetServiceProtocol().AddHandler(this, GetServiceProtocolDescription());
  }

  PersistentCache::GetCacheForProcess()->AddWorkerTaskRunner(
      task_runners_.GetIOTaskRunner());

  return true;
}
複製代碼

Create the platform

// Create the platform view on the platform thread (this thread).
auto platform_view = on_create_platform_view(*shell.get());
if (!platform_view || !platform_view->GetWeakPtr()) {
  return nullptr;
}
複製代碼

CreateVSyncWaiter

// Ask the platform view for the vsync waiter. This will be used by the engine
// to create the animator.
auto vsync_waiter = platform_view->CreateVSyncWaiter();
if (!vsync_waiter) {
  return nullptr;
}
複製代碼

Create the IO manager on the IO thread

// Create the IO manager on the IO thread. The IO manager must be initialized
// first because it has state that the other subsystems depend on. It must
// first be booted and the necessary references obtained to initialize the
// other subsystems.
fml::AutoResetWaitableEvent io_latch;
std::unique_ptr<IOManager> io_manager;
auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
fml::TaskRunner::RunNowOrPostTask(
    io_task_runner,
    [&io_latch,       //
     &io_manager,     //
     &platform_view,  //
     io_task_runner   //
]() {
      io_manager = std::make_unique<IOManager>(
          platform_view->CreateResourceContext(), io_task_runner);
      io_latch.Signal();
    });
io_latch.Wait();

複製代碼

Create the rasterizer on the GPU thread

// Create the rasterizer on the GPU thread.
fml::AutoResetWaitableEvent gpu_latch;
std::unique_ptr<Rasterizer> rasterizer;
fml::WeakPtr<blink::SnapshotDelegate> snapshot_delegate;
fml::TaskRunner::RunNowOrPostTask(
    task_runners.GetGPUTaskRunner(), [&gpu_latch,            //
                                      &rasterizer,           //
                                      on_create_rasterizer,  //
                                      shell = shell.get(),   //
                                      &snapshot_delegate     //
]() {
      if (auto new_rasterizer = on_create_rasterizer(*shell)) {
        rasterizer = std::move(new_rasterizer);
        snapshot_delegate = rasterizer->GetSnapshotDelegate();
      }
      gpu_latch.Signal();
    });

gpu_latch.Wait();
複製代碼

Create the engine on the UI thread

// Create the engine on the UI thread.
fml::AutoResetWaitableEvent ui_latch;
std::unique_ptr<Engine> engine;
fml::TaskRunner::RunNowOrPostTask(
    shell->GetTaskRunners().GetUITaskRunner(),
    fml::MakeCopyable([&ui_latch,                                         //
                       &engine,                                           //
                       shell = shell.get(),                               //
                       isolate_snapshot = std::move(isolate_snapshot),    //
                       shared_snapshot = std::move(shared_snapshot),      //
                       vsync_waiter = std::move(vsync_waiter),            //
                       snapshot_delegate = std::move(snapshot_delegate),  //
                       io_manager = io_manager->GetWeakPtr()              //
]() mutable {
      const auto& task_runners = shell->GetTaskRunners();

      // The animator is owned by the UI thread but it gets its vsync pulses
      // from the platform.
      auto animator = std::make_unique<Animator>(*shell, task_runners,
                                                 std::move(vsync_waiter));

      engine = std::make_unique<Engine>(*shell,                        //
                                        shell->GetDartVM(),            //
                                        std::move(isolate_snapshot),   //
                                        std::move(shared_snapshot),    //
                                        task_runners,                  //
                                        shell->GetSettings(),          //
                                        std::move(animator),           //
                                        std::move(snapshot_delegate),  //
                                        std::move(io_manager)          //
      );
      ui_latch.Signal();
    }));

ui_latch.Wait();
複製代碼

Engine初始化

Engine::Engine(Delegate& delegate,
               blink::DartVM& vm,
               fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
               fml::RefPtr<blink::DartSnapshot> shared_snapshot,
               blink::TaskRunners task_runners,
               blink::Settings settings,
               std::unique_ptr<Animator> animator,
               fml::WeakPtr<blink::SnapshotDelegate> snapshot_delegate,
               fml::WeakPtr<blink::IOManager> io_manager)
    : delegate_(delegate),
      settings_(std::move(settings)),
      animator_(std::move(animator)),
      activity_running_(false),
      have_surface_(false),
      weak_factory_(this) {
  // Runtime controller is initialized here because it takes a reference to this
  // object as its delegate. The delegate may be called in the constructor and
  // we want to be fully initilazed by that point.
  runtime_controller_ = std::make_unique<blink::RuntimeController>(
      *this,                                 // runtime delegate
      &vm,                                   // VM
      std::move(isolate_snapshot),           // isolate snapshot
      std::move(shared_snapshot),            // shared snapshot
      std::move(task_runners),               // task runners
      std::move(snapshot_delegate),          // snapshot delegate
      std::move(io_manager),                 // io manager
      settings_.advisory_script_uri,         // advisory script uri
      settings_.advisory_script_entrypoint,  // advisory script entrypoint
      settings_.idle_notification_callback   // idle notification callback
  );
}
複製代碼

RuntimeController&WindowClient&Window

RuntimeController::RuntimeController(
    RuntimeDelegate& p_client,
    DartVM* p_vm,
    fml::RefPtr<DartSnapshot> p_isolate_snapshot,
    fml::RefPtr<DartSnapshot> p_shared_snapshot,
    TaskRunners p_task_runners,
    fml::WeakPtr<SnapshotDelegate> p_snapshot_delegate,
    fml::WeakPtr<IOManager> p_io_manager,
    std::string p_advisory_script_uri,
    std::string p_advisory_script_entrypoint,
    std::function<void(int64_t)> p_idle_notification_callback)
    : RuntimeController(p_client,
                        p_vm,
                        std::move(p_isolate_snapshot),
                        std::move(p_shared_snapshot),
                        std::move(p_task_runners),
                        std::move(p_snapshot_delegate),
                        std::move(p_io_manager),
                        std::move(p_advisory_script_uri),
                        std::move(p_advisory_script_entrypoint),
                        p_idle_notification_callback,
                        WindowData{/* default window data */}) {}

RuntimeController::RuntimeController(
    RuntimeDelegate& p_client,
    DartVM* p_vm,
    fml::RefPtr<DartSnapshot> p_isolate_snapshot,
    fml::RefPtr<DartSnapshot> p_shared_snapshot,
    TaskRunners p_task_runners,
    fml::WeakPtr<SnapshotDelegate> p_snapshot_delegate,
    fml::WeakPtr<IOManager> p_io_manager,
    std::string p_advisory_script_uri,
    std::string p_advisory_script_entrypoint,
    std::function<void(int64_t)> idle_notification_callback,
    WindowData p_window_data)
    : client_(p_client),
      vm_(p_vm),
      isolate_snapshot_(std::move(p_isolate_snapshot)),
      shared_snapshot_(std::move(p_shared_snapshot)),
      task_runners_(p_task_runners),
      snapshot_delegate_(p_snapshot_delegate),
      io_manager_(p_io_manager),
      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)),
      root_isolate_(
          DartIsolate::CreateRootIsolate(vm_,
                                         isolate_snapshot_,
                                         shared_snapshot_,
                                         task_runners_,
                                         std::make_unique<Window>(this),
                                         snapshot_delegate_,
                                         io_manager_,
                                         p_advisory_script_uri,
                                         p_advisory_script_entrypoint)) {
  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
  root_isolate->SetReturnCodeCallback([this](uint32_t code) {
    root_isolate_return_code_ = {true, code};
  });
  當前對象是ClientWidow對象,動過調用DidCreateIsolate,加載dart:UI庫
  if (auto* window = GetWindowIfAvailable()) {
    tonic::DartState::Scope scope(root_isolate);
    window->DidCreateIsolate();
    if (!FlushRuntimeStateToIsolate()) {
      FML_DLOG(ERROR) << "Could not setup intial isolate state.";
    }
  } else {
    FML_DCHECK(false) << "RuntimeController created without window binding.";
  }
  FML_DCHECK(Dart_CurrentIsolate() == nul
};

}  // namespace blink

#endif  // FLUTTER_RUNTIME_RUNTIME_CONTROLLER_H_

複製代碼

DartIsolate

調用shared_embedder_isolate->SetWindow(std::move(window));對象傳遞RuntimeControllerWindow類中進行綁定

std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
    DartVM* vm,
    fml::RefPtr<DartSnapshot> isolate_snapshot,
    fml::RefPtr<DartSnapshot> shared_snapshot,
    TaskRunners task_runners,
    std::unique_ptr<Window> window,
    fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
    fml::WeakPtr<IOManager> io_manager,
    std::string advisory_script_uri,
    std::string advisory_script_entrypoint,
    Dart_IsolateFlags* flags) {
  TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate");
  Dart_Isolate vm_isolate = nullptr;
  std::weak_ptr<DartIsolate> embedder_isolate;

  char* error = nullptr;

  // Since this is the root isolate, we fake a parent embedder data object. We
  // cannot use unique_ptr here because the destructor is private (since the
  // isolate lifecycle is entirely managed by the VM).
  auto root_embedder_data = std::make_unique<std::shared_ptr<DartIsolate>>(
      std::make_shared<DartIsolate>(
          vm,                            // VM
          std::move(isolate_snapshot),   // isolate snapshot
          std::move(shared_snapshot),    // shared snapshot
          task_runners,                  // task runners
          std::move(snapshot_delegate),  // snapshot delegate
          std::move(io_manager),         // IO manager
          advisory_script_uri,           // advisory URI
          advisory_script_entrypoint,    // advisory entrypoint
          nullptr  // child isolate preparer will be set when this isolate is
                   // prepared to run
          ));

  std::tie(vm_isolate, embedder_isolate) = CreateDartVMAndEmbedderObjectPair(
      advisory_script_uri.c_str(),         // advisory script URI
      advisory_script_entrypoint.c_str(),  // advisory script entrypoint
      nullptr,                             // package root
      nullptr,                             // package config
      flags,                               // flags
      root_embedder_data.get(),            // parent embedder data
      true,                                // is root isolate
      &error                               // error (out)
  );

  if (error != nullptr) {
    free(error);
  }

  if (vm_isolate == nullptr) {
    return {};
  }

  std::shared_ptr<DartIsolate> shared_embedder_isolate =
      embedder_isolate.lock();
  if (shared_embedder_isolate) {
    // Only root isolates can interact with windows.
    shared_embedder_isolate->SetWindow(std::move(window));
  }

  root_embedder_data.release();

  return embedder_isolate;
}
}

複製代碼

Window類初始化過程

CreateRootIsolate 建立 RootIsolate對象

RuntimeController::RuntimeController(.....)
    : client_(p_client),
      .......),
      window_data_(std::move(p_window_data)),
      root_isolate_(
          DartIsolate::CreateRootIsolate(vm_,
                                         isolate_snapshot_,
                                         shared_snapshot_,
                                         task_runners_,
                                         std::make_unique<Window>(this),
                                         snapshot_delegate_,
                                         io_manager_,
                                         p_advisory_script_uri,
                                         p_advisory_script_entrypoint)) {
  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
  root_isolate->SetReturnCodeCallback([this](uint32_t code) {
    root_isolate_return_code_ = {true, code};
  });
  ## Window類初始化過程

  if (auto* window = GetWindowIfAvailable()) {
    tonic::DartState::Scope scope(root_isolate);
    window->DidCreateIsolate();
    if (!FlushRuntimeStateToIsolate()) {
      FML_DLOG(ERROR) << "Could not setup intial isolate state.";
    }
  } else {
    FML_DCHECK(false) << "RuntimeController created without window binding.";
  }
  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
}
複製代碼

Android Native層與libFlutter通訊接口:

在分析完成整個初始化過程這回,在跟進下圖來分析整個調用過程和以上代碼的初始化過程,有助於理解整個運行環境的初始化相關的類和功能及邏輯

flutterplugin1.png

Android端調用JNI層的代碼,使用本地接口和FlutterEngine通訊,在Flutter for Android 中經過FlutterJNI中相關的本地方法,platform_view_android_jni在第一次加載so庫是進行初始化:

/io/flutter/embedding/engine/FlutterJNI.class engine/src/flutter/shell/platform/android/platform_view_android_jni.cc

public class FlutterJNI {
    @UiThread
    public static native boolean nativeGetIsSoftwareRenderingEnabled();
    @UiThread
    public static native String nativeGetObservatoryUri();
    private native void nativeSurfaceCreated(long var1, Surface var3);
    private native void nativeSurfaceChanged(long var1, int var3, int var4);
    private native void nativeSurfaceDestroyed(long var1);
    private native void nativeSetViewportMetrics(long var1, float var3, int var4, int var5, int var6, int var7, int var8, int var9, int var10, int var11, int var12, int var13);
    private native Bitmap nativeGetBitmap(long var1);
    private native void nativeDispatchPointerDataPacket(long var1, ByteBuffer var3, int var4);
    private native void nativeDispatchSemanticsAction(long var1, int var3, int var4, ByteBuffer var5, int var6);
    private native void nativeSetSemanticsEnabled(long var1, boolean var3);
    private native void nativeSetAccessibilityFeatures(long var1, int var3);
    private native void nativeRegisterTexture(long var1, long var3, SurfaceTexture var5);
    private native void nativeMarkTextureFrameAvailable(long var1, long var3);
    private native void nativeUnregisterTexture(long var1, long var3);
    private native long nativeAttach(FlutterJNI var1, boolean var2);
    private native void nativeDetach(long var1);
    private native void nativeDestroy(long var1);
    private native void nativeRunBundleAndSnapshotFromLibrary(long var1, @NonNull String[] var3, @Nullable String var4, @Nullable String var5, @NonNull AssetManager var6);
    private native void nativeDispatchEmptyPlatformMessage(long var1, String var3, int var4);
    private native void nativeDispatchPlatformMessage(long var1, String var3, ByteBuffer var4, int var5, int var6);
    private native void nativeInvokePlatformMessageEmptyResponseCallback(long var1, int var3);
    private native void nativeInvokePlatformMessageResponseCallback(long var1, int var3, ByteBuffer var4, int var5);
}
複製代碼

引擎元代碼中使用動態JNI的方式註冊相關方法: engine/src/flutter/shell/platform/android/platform_view_android_jni.cc

調用Register方法註冊本地方法:

bool RegisterApi(JNIEnv* env) {
static const JNINativeMethod flutter_jni_methods[] = {
  // Start of methods from FlutterNativeView
  {
      .name = "nativeAttach",
      .signature = "(Lio/flutter/embedding/engine/FlutterJNI;Z)J",
      .fnPtr = reinterpret_cast<void*>(&shell::AttachJNI),
  },
  {
      .name = "nativeDestroy",
      .signature = "(J)V",
      .fnPtr = reinterpret_cast<void*>(&shell::DestroyJNI),
  },
  {
      .name = "nativeRunBundleAndSnapshotFromLibrary",
      .signature = "(J[Ljava/lang/String;Ljava/lang/String;"
                   "Ljava/lang/String;Landroid/content/res/AssetManager;)V",
      .fnPtr =
          reinterpret_cast<void*>(&shell::RunBundleAndSnapshotFromLibrary),
  },
};

if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
                     arraysize(flutter_jni_methods)) != 0) {
FML_LOG(ERROR) << "Failed to RegisterNatives with FlutterJNI";
return false;
}
複製代碼
`engine/src/flutter/shell/common/shell.cc`做爲一個中樞控制做用,使用弱引用來保存PlatformView,Android,ios保存使用shell中Platform下的Platefrom實現來處理平臺相關的View,Shell的初始化是在`engine/src/flutter/shell/platform/android/android_shell_holder.cc`,`FlutterMain::Get().GetSettings()`編譯時的配置文件`engine/src/flutter/common/settings.cc`,`flutterJNI`是android層的代碼,`is_background_view`是在java層FlutterNativeView,這是Java和JNI的通訊,數據傳輸邏輯處理,FlutterNativeView的構造方法中調用JNI代碼,初始化`android_shell_holder`使用這個類來所有`Shell`這個類



### SurfaceView初始化

### Java SurfaceView 初始化

getFlutterJNI 初始化SurfaceView
```Java
this.mSurfaceCallback = new Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
        FlutterView.this.assertAttached();
        FlutterView.this.mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        FlutterView.this.assertAttached();
        FlutterView.this.mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        FlutterView.this.assertAttached();
        FlutterView.this.mNativeView.getFlutterJNI().onSurfaceDestroyed();
    }
};


複製代碼

JNI 初始化SurfaceView

/Users/cangck/engine/src/flutter/shell/platform/android/platform_view_android_jni.cc

SurfaceCreated

static void SurfaceCreated(JNIEnv* env, jobject jcaller, jlong shell_holder, jobject jsurface) {
  // Note: This frame ensures that any local references used by
  // ANativeWindow_fromSurface are released immediately. This is needed as a
  // workaround for https://code.google.com/p/android/issues/detail?id=68174
  fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
  auto window = fml::MakeRefCounted<AndroidNativeWindow>(
      ANativeWindow_fromSurface(env, jsurface));
  ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));
}
複製代碼

SurfaceChanged

static void SurfaceChanged(JNIEnv* env, jobject jcaller, jlong shell_holder, jint width, jint height) {
  ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyChanged(
      SkISize::Make(width, height));
}

複製代碼

SurfaceDestroyed

static void SurfaceDestroyed(JNIEnv* env, jobject jcaller, jlong shell_holder) {
  ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyDestroyed();
}
複製代碼

總結

經過上面的分析,咱們已經大概瞭解了Android啓動,初始化Flutter引擎的過程: 1.Androidapp啓動時加載libFlutter.so庫 2.libFlutter.so加載完成後JNI_onLoad方法回調開始初始化引擎 3.FlutterMain::Register初始化Android對應的JIN相關的Native方法入口 4.PlatformViewandroid初始化,處理SurfaceView相關的圖像繪製接口 5.FlutterView初始化,調用本地方法添加SurfaceView到libFlutter.so中進行關聯 6.AttachJNI方法開始初始化Dart虛擬機 7.AndroidShellHoler開始處理相關的線程模型和運行環境 8.Shell初始化引擎文件 9.DartVM啓動 10.加載第三方庫文件 11.Engine初始化 12.初始化FlutterUI層的接口Window類 13.初始化DartIsolateDart運行環境 通過上面的步驟,Flutter引擎初始化已經完成,大概的流程和框架已經完成,已經能夠看到Flutterengine的一個大致輪廓,在後續的工做中不斷的優化,學習,補充完整

在學習一門新語言學,主要先學習總體的邏輯,不要太注重細節,輪廓摸清楚之後,在後續的開發中大腦中有一個框架,在遇到問題的快速的定位是哪裏出現的問題,查看源碼,在不斷的開發中完善細節,沒有任何一我的能夠一次性搞定全部的問題,框架清楚之後在開發過程當中可以加快開發進度和處理bug的時間。

鍥而不捨、按部就班---共勉

相關文章
相關標籤/搜索