在 FlutterEngin启动流程&android 和 FlutterActivityDelegate初始化UI相关的内容 两篇代码分析的过程中,已经分析了加载 libflutter.so
的初始化话过程, platform_view_android_jni.cc
中调用 AttachJNI
初始化 AndroidShellHolder
对象对平台进行初始化,进行来分析FlutterEngine初始化过程。
!!! info "Flutter Engine初始化过程"
* 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
Java加载Flutter.so库完成时,开始初始化Flutter引擎
1.注册Flutter层的代码
2.初始化AndroidView
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
函数到JNI init
函数并且初始化相关的引擎
2.加载 FlutterMain
中的所有native函数
开始初始化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.初始化FlutterMain g_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) // ); } 复制代码
DartVM::ForProcess
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的时间。
持之以恒、循序渐进---共勉