在FlutterEngin啓動流程&android和FlutterActivityDelegate初始化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.so中Android端的入口函數engine/src/flutter/shell/platform/android/library_loader.cc
ios
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;
}
複製代碼
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端通訊
在下圖中:
初始化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;
}
複製代碼
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();
}
複製代碼
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();
}
複製代碼
接下來進行分析在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:主要是管理flutter engine 在Platform端的入口:
// 參數說明:
//
// 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";
}
});
}
}
複製代碼
建立一個線程來對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要求Embeder提供四個Task Runner,Embeder指的是將引擎移植到平臺的中間層代碼。這四個主要的Task Runner包括:
flutterThread.jpeg
根據在java層調用native層的調用是傳入的參數判斷建立線程的類型:
/engine/src/flutter/fml/thread.cc
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");
}
}
複製代碼
在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建立一個專用的線程。
ThreadHost建立完成四個線程以後,在建立四個TaskRunner
來管理Platform,UI,GPU,IO線程中的任務engine/src/flutter/fml/task_runner.h
提供四個方法處理提交到MessageLoop的任務的執行時間和關聯到消息隊列
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 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 類的初始化,主要負責管理客戶端相關的資源/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"
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) //
);
}
複製代碼
Dart VM 虛擬機在Shell建立的時候初始化:auto vm = blink::DartVM::ForProcess(settings);
,/engine/src/flutter/shell/common/shell.cc
,Shell::Create,Dart虛擬機的分析,在後續在進行擴展
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;
}
複製代碼
PerformInitializationTasks
,/engine/src/flutter/shell/common/shell.cc
// 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.";
}
}
});
}
複製代碼
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分的一下初始化信息
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
方法時調用
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 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();
複製代碼
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::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_
複製代碼
調用shared_embedder_isolate->SetWindow(std::move(window));
對象傳遞RuntimeController
到Window
類中進行綁定
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;
}
}
複製代碼
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);
}
複製代碼
在分析完成整個初始化過程這回,在跟進下圖來分析整個調用過程和以上代碼的初始化過程,有助於理解整個運行環境的初始化相關的類和功能及邏輯
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();
}
};
複製代碼
/Users/cangck/engine/src/flutter/shell/platform/android/platform_view_android_jni.cc
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));
}
複製代碼
static void SurfaceChanged(JNIEnv* env, jobject jcaller, jlong shell_holder, jint width, jint height) {
ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyChanged(
SkISize::Make(width, height));
}
複製代碼
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的時間。
鍥而不捨、按部就班---共勉