Flutter在Android平台上启动时,Native层做了什么?,
Flutter在Android平台上启动时,Native层做了什么?,
前言
接上回 Flutter——在Android平台上的启动流程浅析,
我们来看看穿插在其中的native层都做了什么。
由于代码较多,我会将说明以注释的形式写在代码里,并删除非必要代码
FlutterLoader
在flutterLoader中的这个startInitialization()方法中:
- public void startInitialization(@NonNull Context applicationContext, @NonNull FlutterLoader.Settings settings) {
- if (this.settings == null) {
- if (Looper.myLooper() != Looper.getMainLooper()) {
- throw new IllegalStateException("startInitialization must be called on the main thread");
- } else {
- ....
- Callable<FlutterLoader.InitResult> initTask = new Callable<FlutterLoader.InitResult>() {
- public FlutterLoader.InitResult call() {
- ....
- ///这里是在子线程执行的
- System.loadLibrary("flutter");
- ....
- return new FlutterLoader.InitResult(PathUtils.getFilesDir(appContext), PathUtils.getCacheDirectory(appContext), PathUtils.getDataDirectory(appContext));
- }
- };
- this.initResultFuture = Executors.newSingleThreadExecutor().submit(initTask);
- }
- }
- }
System.loadLibrary("flutter");并不是简单地加载flutter框架代码,它最终会进入native中的JNI_OnLoad方法:
- // This is called by the VM when the shared library is first loaded.
- JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
- // 初始化 JVM (只是将虚拟机进行一个保存)
- // 之后关联到当前线程上
- fml::jni::InitJavaVM(vm);
- JNIEnv* env = fml::jni::AttachCurrentThread();
- bool result = false;
- // 注册 FlutterMain.
- result = flutter::FlutterMain::Register(env);
- FML_CHECK(result);
- // 注册 PlatformView
- // 这里会注册大量的方法,使c++和java可以互相调用
- result = flutter::PlatformViewAndroid::Register(env);
- FML_CHECK(result);
- // 注册 VSyncWaiter.
- // 这里将java的VSyncWaiter类中的方法与
- // native中的VsyncWaiterAndroid的映射,便可以互相调用
- result = flutter::VsyncWaiterAndroid::Register(env);
- FML_CHECK(result);
- return JNI_VERSION_1_4;
- }
- tip:PlatformViewAndroid路径为:engine/shell/platform/android
有兴趣的话,可以看看
整体来看,这里主要是保存了jvm,同时对c++和java的方法进行了映射以便双方可以互相调用。
至此FlutterApplication中所拉起的native代码就简单概括完了,我们接着FlutterActivity中所调用native代码。
FlutterActivity & onCreate
这里需要提一下,目前你搜索FlutterActivity这个类,会发现有两个:
- android/FlutterActivity 这个是最新的
- app/FlutterActivity 已过期
经过一系列调用,具体见这篇文章: Flutter——在Android平台上的启动流程浅析,
会初始化flutterEngine,构造函数如下:
- //很长,但是其中初始化的东西还是比较有用的
- //所以我觉得有必要贴一下
- /** Fully configurable {@code FlutterEngine} constructor. */
- public FlutterEngine(
- @NonNull Context context,
- @NonNull FlutterLoader flutterLoader,
- @NonNull FlutterJNI flutterJNI,
- @NonNull PlatformViewsController platformViewsController,
- @Nullable String[] dartVmArgs,
- boolean automaticallyRegisterPlugins,
- boolean waitForRestorationData) {
- this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets());
- this.dartExecutor.onAttachedToJNI();
- accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI);
- keyEventChannel = new KeyEventChannel(dartExecutor);
- lifecycleChannel = new LifecycleChannel(dartExecutor);
- localizationChannel = new LocalizationChannel(dartExecutor);
- mouseCursorChannel = new MouseCursorChannel(dartExecutor);
- navigationChannel = new NavigationChannel(dartExecutor);
- platformChannel = new PlatformChannel(dartExecutor);
- restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);
- settingsChannel = new SettingsChannel(dartExecutor);
- systemChannel = new SystemChannel(dartExecutor);
- textInputChannel = new TextInputChannel(dartExecutor);
- this.localizationPlugin = new LocalizationPlugin(context, localizationChannel);
- this.flutterJNI = flutterJNI;
- flutterLoader.startInitialization(context.getApplicationContext());
- ///注意这里
- flutterLoader.ensureInitializationComplete(context, dartVmArgs);
- flutterJNI.addEngineLifecycleListener(engineLifecycleListener);
- flutterJNI.setPlatformViewsController(platformViewsController);
- flutterJNI.setLocalizationPlugin(localizationPlugin);
- attachToJni();
- // TODO(mattcarroll): FlutterRenderer is temporally coupled to attach(). Remove that coupling if
- // possible.
- this.renderer = new FlutterRenderer(flutterJNI);
- this.platformViewsController = platformViewsController;
- this.platformViewsController.onAttachedToJNI();
- this.pluginRegistry =
- new FlutterEnginePluginRegistry(context.getApplicationContext(), this, flutterLoader);
- if (automaticallyRegisterPlugins) {
- registerPlugins();
- }
- }
整个构造函数会初始化大量channel,同时进行一些native方法注册,其中:
- flutterLoader.ensureInitializationComplete(context, dartVmArgs);
会转到native,详细代码如下:
- ///此方法会阻塞,直到native 系统工作执行完毕
- public void ensureInitializationComplete(
- @NonNull Context applicationContext, @Nullable String[] args) {
- if (initialized) {
- return;
- }
- if (Looper.myLooper() != Looper.getMainLooper()) {
- throw new IllegalStateException(
- "ensureInitializationComplete must be called on the main thread");
- }
- if (settings == null) {
- throw new IllegalStateException(
- "ensureInitializationComplete must be called after startInitialization");
- }
- ///收集各种文件路径
- try {
- InitResult result = initResultFuture.get();
- List<String> shellArgs = new ArrayList<>();
- shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");
- ApplicationInfo applicationInfo = getApplicationInfo(applicationContext);
- shellArgs.add(
- "--icu-native-lib-path="
- + applicationInfo.nativeLibraryDir
- + File.separator
- + DEFAULT_LIBRARY);
- if (args != null) {
- Collections.addAll(shellArgs, args);
- }
- String kernelPath = null;
- if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) {
- String snapshotAssetPath = result.dataDirPath + File.separator + flutterAssetsDir;
- kernelPath = snapshotAssetPath + File.separator + DEFAULT_KERNEL_BLOB;
- shellArgs.add("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath);
- shellArgs.add("--" + VM_SNAPSHOT_DATA_KEY + "=" + vmSnapshotData);
- shellArgs.add("--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + isolateSnapshotData);
- } else {
- shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + aotSharedLibraryName);
- // Most devices can load the AOT shared library based on the library name
- // with no directory path. Provide a fully qualified path to the library
- // as a workaround for devices where that fails.
- shellArgs.add(
- "--"
- + AOT_SHARED_LIBRARY_NAME
- + "="
- + applicationInfo.nativeLibraryDir
- + File.separator
- + aotSharedLibraryName);
- }
- shellArgs.add("--cache-dir-path=" + result.engineCachesPath);
- if (settings.getLogTag() != null) {
- shellArgs.add("--log-tag=" + settings.getLogTag());
- }
- long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;
- // TODO(cyanlaz): Remove this when dynamic thread merging is done.
- // https://github.com/flutter/flutter/issues/59930
- Bundle bundle = applicationInfo.metaData;
- if (bundle != null) {
- boolean use_embedded_view = bundle.getBoolean("io.flutter.embedded_views_preview");
- if (use_embedded_view) {
- shellArgs.add("--use-embedded-view");
- }
- }
- /// 拉起native
- FlutterJNI.nativeInit(
- applicationContext,
- shellArgs.toArray(new String[0]),
- kernelPath,
- result.appStoragePath,
- result.engineCachesPath,
- initTimeMillis);
- initialized = true;
- } catch (Exception e) {
- Log.e(TAG, "Flutter initialization failed.", e);
- throw new RuntimeException(e);
- }
- }
这里会将相关的信息通过FlutterJNI.nativeInit,即:
- ///native 方法
- public static native void nativeInit(
- @NonNull Context context,
- @NonNull String[] args,
- @Nullable String bundlePath,
- @NonNull String appStoragePath,
- @NonNull String engineCachesPath,
- long initTimeMillis);
传递到native层,还记得上部分我们注册的flutterMain方法吗?
FlutterMain::Register
- bool FlutterMain::Register(JNIEnv* env) {
- static const JNINativeMethod methods[] = {
- {
- ///看这里 name是方法名的意思
- .name = "nativeInit",
- .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
- "lang/String;Ljava/lang/String;Ljava/lang/String;J)V",
- ///方法&Init的地址被保存在了fnPtr上
- .fnPtr = reinterpret_cast<void*>(&Init),
- },
- {
- .name = "nativePrefetchDefaultFontManager",
- .signature = "()V",
- .fnPtr = reinterpret_cast<void*>(&PrefetchDefaultFontManager),
- },
- };
- jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
- if (clazz == nullptr) {
- return false;
- }
- return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
- }
通过指针.fnPtr = reinterpret_cast(&Init),便会拉起它的FlutterMain::Init方法。
- void FlutterMain::Init(JNIEnv* env,
- jclass clazz,
- jobject context,
- jobjectArray jargs,
- jstring kernelPath,
- jstring appStoragePath,
- jstring engineCachesPath,
- jlong initTimeMillis) {
- std::vector<std::string> args;
- ///tag
- args.push_back("flutter");
- ///将上面我们收集的那些路径信息保存到 args中
- ///以‘j’ 表示java传过来的。
- 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);
- ///engine启动时间
- int64_t init_time_micros = initTimeMillis * 1000;
- settings.engine_start_timestamp =
- std::chrono::microseconds(Dart_TimelineGetMicros() - init_time_micros);
- // Restore the callback cache.
- // TODO(chinmaygarde): Route all cache file access through FML and remove this
- // setter.
- flutter::DartCallbackCache::SetCachePath(
- fml::jni::JavaStringToString(env, appStoragePath));
- ///初始化缓存路径
- fml::paths::InitializeAndroidCachesPath(
- fml::jni::JavaStringToString(env, engineCachesPath));
- ///加载缓存
- flutter::DartCallbackCache::LoadCacheFromDisk();
- if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) {
- // Check to see if the appropriate kernel files are present and configure
- // settings accordingly.
- auto application_kernel_path =
- fml::jni::JavaStringToString(env, kernelPath);
- 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)));
- g_flutter_main->SetupObservatoryUriCallback(env);
- }
以上主要是对java传过来的数据进行保存,至此由flutterLoader.ensureInitializationComplete所引起的native执行完毕,在其后面会执行attachToJni()。
FlutterActivity& attachToJni()
attachToJni()最终会调用flutterJNI.attachToNative(false):
- ///这步完成后,android便可以与engine通信了
- @UiThread
- public void attachToNative(boolean isBackgroundView) {
- ensureRunningOnMainThread();
- ensureNotAttachedToNative();
- nativePlatformViewId = nativeAttach(this, isBackgroundView);
- }
- private native long nativeAttach(@NonNull FlutterJNI flutterJNI, boolean isBackgroundView);
此方法会调用native的:
- static jlong AttachJNI(JNIEnv* env,
- jclass clazz,
- jobject flutterJNI,
- jboolean is_background_view) {
- fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
- std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
- std::make_shared<PlatformViewAndroidJNIImpl>(java_object);
- ///主要就是初始化一个 shell holder
- auto shell_holder = std::make_unique<AndroidShellHolder>(
- FlutterMain::Get().GetSettings(), jni_facade, is_background_view);
- if (shell_holder->IsValid()) {
- return reinterpret_cast<jlong>(shell_holder.release());
- } else {
- return 0;
- }
- }
我们来看一下AndroidShellHolder.cc的实现
AndroidShellHolder & gpu/ui/io线程的创建
它有一个100多行的构造函数:
- AndroidShellHolder::AndroidShellHolder(
- flutter::Settings settings,
- std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
- bool is_background_view)
- : settings_(std::move(settings)), jni_facade_(jni_facade) {
- static size_t shell_count = 1;
- auto thread_label = std::to_string(shell_count++);
- FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) ==
- 0);
- ///这里我们传递的是false
- if (is_background_view) {
- thread_host_ = {thread_label, ThreadHost::Type::UI};
- } else {
- /// 会创建三个线程 分别是 UI\GPU\IO
- thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
- ThreadHost::Type::IO};
- }
- // Detach from JNI when the UI and raster threads exit.
- // UI和raster线程退出时,与JNI分离
- // raster就是gpu线程,它将我们的绘制指令转为gpu指令
- 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_.raster_thread->GetTaskRunner()->PostTask(jni_exit_task);
- }
- fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
- Shell::CreateCallback<PlatformView> on_create_platform_view =
- [is_background_view, &jni_facade, &weak_platform_view](Shell& shell) {
- std::unique_ptr<PlatformViewAndroid> platform_view_android;
- if (is_background_view) {
- ...走下面
- } else {
- ///初始化了一个PlatformViewAndroid
- platform_view_android = std::make_unique<PlatformViewAndroid>(
- shell, // delegate
- shell.GetTaskRunners(), // task runners
- jni_facade, // JNI interop
- shell.GetSettings()
- .enable_software_rendering // use software rendering
- );
- }
- weak_platform_view = platform_view_android->GetWeakPtr();
- shell.OnDisplayUpdates(DisplayUpdateType::kStartup,
- {Display(jni_facade->GetDisplayRefreshRate())});
- return platform_view_android;
- };
- Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
- return std::make_unique<Rasterizer>(shell);
- };
- // The current thread will be used as the platform thread. Ensure that the
- // message loop is initialized.
- // 初始化native的 message loop
- // gpu/ui/io它们也有各自的 msg loop
- fml::MessageLoop::EnsureInitializedForCurrentThread();
- ///初始化对应线程的task runner
- /// 这样我们便可以向指定线程post 任务
- 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_.raster_thread->GetTaskRunner();
- ui_runner = thread_host_.ui_thread->GetTaskRunner();
- io_runner = thread_host_.io_thread->GetTaskRunner();
- }
- flutter::TaskRunners task_runners(thread_label, // label
- platform_runner, // platform
- gpu_runner, // raster
- ui_runner, // ui
- io_runner // io
- );
- ///提高ui 和 gpu线程等级
- ///线程值 越小 等级越高
- task_runners.GetRasterTaskRunner()->PostTask([]() {
- // Android describes -8 as "most important display threads, for
- // compositing the screen and retrieving input events". Conservatively
- // set the raster 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";
- }
- });
- ///创建shell
- shell_ =
- Shell::Create(task_runners, // task runners
- GetDefaultPlatformData(), // window data
- settings_, // settings
- on_create_platform_view, // platform view create callback
- on_create_rasterizer // rasterizer create callback
- );
- platform_view_ = weak_platform_view;
- FML_DCHECK(platform_view_);
- is_valid_ = shell_ != nullptr;
- }
Shell
我们接着看一下 shell_的创建:
- std::unique_ptr<Shell> Shell::Create(
- TaskRunners task_runners,
- const PlatformData platform_data,
- Settings settings,
- Shell::CreateCallback<PlatformView> on_create_platform_view,
- Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
- PerformInitializationTasks(settings);
- PersistentCache::SetCacheSkSL(settings.cache_sksl);
- TRACE_EVENT0("flutter", "Shell::Create");
- ///创建虚拟机
- auto vm = DartVMRef::Create(settings);
- FML_CHECK(vm) << "Must be able to initialize the VM.";
- auto vm_data = vm->GetVMData();
- return Shell::Create(std::move(task_runners), //
- std::move(platform_data), //
- std::move(settings), //
- vm_data->GetIsolateSnapshot(), // isolate snapshot
- on_create_platform_view, //
- on_create_rasterizer, //
- std::move(vm) //
- );
- }
DartVMRef::Create
- DartVMRef DartVMRef::Create(Settings settings,
- fml::RefPtr<DartSnapshot> vm_snapshot,
- fml::RefPtr<DartSnapshot> isolate_snapshot) {
- std::scoped_lock lifecycle_lock(gVMMutex);
- ...删除一些代码
- //这里对已有的虚拟机进行复用
- if (auto vm = gVM.lock()) {
- FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was "
- "already running. Ignoring arguments for current VM "
- "create call and reusing the old VM.";
- // There was already a running VM in the process,
- return DartVMRef{std::move(vm)};
- }
- ...删除一些代码
- //如果没有,就重新创建一个虚拟机
- auto isolate_name_server = std::make_shared<IsolateNameServer>();
- auto vm = DartVM::Create(std::move(settings), //
- std::move(vm_snapshot), //
- std::move(isolate_snapshot), //
- isolate_name_server //
- );
- ...删除一些代码
- return DartVMRef{std::move(vm)};
- }
我们继续看shell的创建,最终会调用CreateShellOnPlatformThread。
Shell & CreateShellOnPlatformThread
- std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
- DartVMRef vm,
- TaskRunners task_runners,
- const PlatformData platform_data,
- Settings settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
- const Shell::CreateCallback<PlatformView>& on_create_platform_view,
- const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
- ...
- ///创建对象
- auto shell =
- std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
- // 创建rasterizer :工作在gpu线程
- // 这里要说一下,gpu线程还是在cpu上的,只是这个线程叫gpu 而已
- std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
- auto rasterizer_future = rasterizer_promise.get_future();
- std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise;
- auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
- fml::TaskRunner::RunNowOrPostTask(
- task_runners.GetRasterTaskRunner(), [&rasterizer_promise, //
- &snapshot_delegate_promise,
- on_create_rasterizer, //
- shell = shell.get() //
- ]() {
- TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
- std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
- snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
- rasterizer_promise.set_value(std::move(rasterizer));
- });
- // 在当前线程(platform thread)创建platform view.
- 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;
- }
- ...删除部分代码...
- ///通过向 io线程post task 来创建 io manager
- fml::TaskRunner::RunNowOrPostTask(
- io_task_runner,
- [&io_manager_promise, //
- &weak_io_manager_promise, //
- &unref_queue_promise, //
- platform_view = platform_view->GetWeakPtr(), //
- io_task_runner, //
- is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() //
- ]() {
- TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
- auto io_manager = std::make_unique<ShellIOManager>(
- platform_view.getUnsafe()->CreateResourceContext(),
- is_backgrounded_sync_switch, io_task_runner);
- weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
- unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
- io_manager_promise.set_value(std::move(io_manager));
- });
- // Send dispatcher_maker to the engine constructor because shell won't have
- // platform_view set until Shell::Setup is called later.
- auto dispatcher_maker = platform_view->GetDispatcherMaker();
- // 在ui线程创建engine
- // 这里的engine指针被跨线程使用
- std::promise<std::unique_ptr<Engine>> engine_promise;
- auto engine_future = engine_promise.get_future();
- fml::TaskRunner::RunNowOrPostTask(
- shell->GetTaskRunners().GetUITaskRunner(),
- fml::MakeCopyable([&engine_promise, //
- shell = shell.get(), //
- &dispatcher_maker, //
- &platform_data, //
- isolate_snapshot = std::move(isolate_snapshot), //
- vsync_waiter = std::move(vsync_waiter), //
- &weak_io_manager_future, //
- &snapshot_delegate_future, //
- &unref_queue_future //
- ]() mutable {
- TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
- const auto& task_runners = shell->GetTaskRunners();
- // 创建animator(ui线程)
- auto animator = std::make_unique<Animator>(*shell, task_runners,
- std::move(vsync_waiter));
- engine_promise.set_value(std::make_unique<Engine>(
- *shell, //
- dispatcher_maker, //
- *shell->GetDartVM(), //
- std::move(isolate_snapshot), //
- task_runners, //
- platform_data, //
- shell->GetSettings(), //
- std::move(animator), //
- weak_io_manager_future.get(), //
- unref_queue_future.get(), //
- snapshot_delegate_future.get() //
- ));
- }));
- if (!shell->Setup(std::move(platform_view), //
- engine_future.get(), //
- rasterizer_future.get(), //
- io_manager_future.get()) //
- ) {
- return nullptr;
- }
- return shell;
- }
由于代码太长,这里再汇总一下:
shell初始化之后,还有分别在io/ui/gpu/platform线程创建以下对象:
- rasterizer 在gpu线程工作,负责将绘制指令转为gpu指令
- platform view 在当前线程(platform thread)
- engine 和 animator 在ui线程工作
flutter最终会通过animator向platformView 申请VSync信号
接下来我们再看一下上面代码中对engine的初始化。
Engine
代码相对较少,但是连接的东西非常多:
- Engine::Engine(Delegate& delegate,
- const PointerDataDispatcherMaker& dispatcher_maker,
- DartVM& vm,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
- TaskRunners task_runners,
- const PlatformData platform_data,
- Settings settings,
- std::unique_ptr<Animator> animator,
- fml::WeakPtr<IOManager> io_manager,
- fml::RefPtr<SkiaUnrefQueue> unref_queue,
- fml::WeakPtr<SnapshotDelegate> snapshot_delegate)
- : Engine(delegate,
- dispatcher_maker,
- vm.GetConcurrentWorkerTaskRunner(),
- task_runners,
- settings,
- std::move(animator),
- io_manager,
- nullptr) {
- runtime_controller_ = std::make_unique<RuntimeController>(
- *this, // runtime delegate
- &vm, // VM
- std::move(isolate_snapshot), // isolate snapshot
- task_runners_, // task runners
- std::move(snapshot_delegate), // snapshot delegate
- GetWeakPtr(), // hint freed delegate
- std::move(io_manager), // io manager
- std::move(unref_queue), // Skia unref queue
- image_decoder_.GetWeakPtr(), // image decoder
- settings_.advisory_script_uri, // advisory script uri
- settings_.advisory_script_entrypoint, // advisory script entrypoint
- settings_.idle_notification_callback, // idle notification callback
- platform_data, // platform data
- settings_.isolate_create_callback, // isolate create callback
- settings_.isolate_shutdown_callback, // isolate shutdown callback
- settings_.persistent_isolate_data // persistent isolate data
- );
- }
就是创建了一个runtime_controller_ ,你可以将runtime controller 看做native、platform和flutter的一个纽带。
小结
经过上面一系列的代码,可能有点晕,概括来讲Flutter Activity在注册flutterMain过程中会创建初始化shell,而在这个初始化的过程中,我们分别会创建三个线程,算上当前线程的话,就是4个:
- platform 线程(当前线程)
- ui 线程
- gpu 线程
- io 线程
并初始化一系列重要对象。
好的,我们再回到主线,onCreate()已经过了,下面我们可以看一下onStart()生命周期:
FlutterActivity & onStart
此方法会调用 delegate.onStart(); 并最终调用FlutterJNI的native方法:
- private native void nativeRunBundleAndSnapshotFromLibrary(
- long nativePlatformViewId,
- @NonNull String bundlePath,
- @Nullable String entrypointFunctionName,
- @Nullable String pathToEntrypointFunction,
- @NonNull AssetManager manager);
从这里开始,其终点就是执行dart的代码。
Launch
接着我们看一下native方法:
(位置在platform_view_android_jni_impl.cc)
- static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
- jobject jcaller,
- jlong shell_holder,
- jstring jBundlePath,
- jstring jEntrypoint,
- jstring jLibraryUrl,
- jobject jAssetManager) {
- ...删除部分代码
- ///这里主要是根据参数,生成一个config 并用于启动
- /// 我们的 默认启动入口 'main()'就在这个config里
- ANDROID_SHELL_HOLDER->Launch(std::move(config));
- }
我们接着看Launch(std::move(config));方法:
- void AndroidShellHolder::Launch(RunConfiguration config) {
- if (!IsValid()) {
- return;
- }
- shell_->RunEngine(std::move(config));
- }
又调用了 run engine 方法:
- void Shell::RunEngine(
- RunConfiguration run_configuration,
- const std::function<void(Engine::RunStatus)>& result_callback) {
- ...删除一些代码
- ///向 ui线程post了一个任务
- fml::TaskRunner::RunNowOrPostTask(
- task_runners_.GetUITaskRunner(),
- fml::MakeCopyable(
- [run_configuration = std::move(run_configuration),
- weak_engine = weak_engine_, result]() mutable {
- if (!weak_engine) {
- FML_LOG(ERROR)
- << "Could not launch engine with configuration - no engine.";
- result(Engine::RunStatus::Failure);
- return;
- }
- ///调用engine的run方法
- auto run_result = weak_engine->Run(std::move(run_configuration));
- if (run_result == flutter::Engine::RunStatus::Failure) {
- FML_LOG(ERROR) << "Could not launch engine with configuration.";
- }
- result(run_result);
- }));
- }
Engin.run()
- Engine::RunStatus Engine::Run(RunConfiguration configuration) {
- if (!configuration.IsValid()) {
- FML_LOG(ERROR) << "Engine run configuration was invalid.";
- return RunStatus::Failure;
- }
- ///获取要执行的 dart代码入口点
- ///这里就是 main方法 from mian.dart
- last_entry_point_ = configuration.GetEntrypoint();
- last_entry_point_library_ = configuration.GetEntrypointLibrary();
- ....
- ///调用了LaunchRootIsolate方法
- if (!runtime_controller_->LaunchRootIsolate(
- settings_, //
- configuration.GetEntrypoint(), //
- configuration.GetEntrypointLibrary(), //
- configuration.TakeIsolateConfiguration()) //
- ) {
- return RunStatus::Failure;
- }
- ...删除部分代码
- return Engine::RunStatus::Success;
- }
LaunchRootIsolate
- bool RuntimeController::LaunchRootIsolate(
- const Settings& settings,
- std::optional<std::string> dart_entrypoint,
- std::optional<std::string> dart_entrypoint_library,
- std::unique_ptr<IsolateConfiguration> isolate_configuration) {
- if (root_isolate_.lock()) {
- FML_LOG(ERROR) << "Root isolate was already running.";
- return false;
- }
- ///创建一个 ‘运行’的 root isolate
- auto strong_root_isolate =
- DartIsolate::CreateRunningRootIsolate(
- settings, // 配置
- isolate_snapshot_, // 快照
- task_runners_, //
- std::make_unique<PlatformConfiguration>(this), // 平台配置
- snapshot_delegate_, //
- hint_freed_delegate_, //
- io_manager_, // io管理运行在Io线程
- unref_queue_, //
- image_decoder_, // 图片解码
- advisory_script_uri_, //
- advisory_script_entrypoint_, //
- DartIsolate::Flags{}, //
- isolate_create_callback_, //
- isolate_shutdown_callback_, //
- dart_entrypoint, // 入口 方法(main.dart)
- dart_entrypoint_library, // 入口库
- std::move(isolate_configuration) //
- )
- .lock();
- ...删除部分代码
- return true;
- }
我们看一下DartIsolate的CreateRunningRootIsolate方法
DartIsolate::CreateRunningRootIsolate
- std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
- const Settings& settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
- TaskRunners task_runners,
- std::unique_ptr<PlatformConfiguration> platform_configuration,
- fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
- fml::WeakPtr<HintFreedDelegate> hint_freed_delegate,
- fml::WeakPtr<IOManager> io_manager,
- fml::RefPtr<SkiaUnrefQueue> skia_unref_queue,
- fml::WeakPtr<ImageDecoder> image_decoder,
- std::string advisory_script_uri,
- std::string advisory_script_entrypoint,
- Flags isolate_flags,
- const fml::closure& isolate_create_callback,
- const fml::closure& isolate_shutdown_callback,
- std::optional<std::string> dart_entrypoint,
- std::optional<std::string> dart_entrypoint_library,
- std::unique_ptr<IsolateConfiguration> isolate_configration) {
- ...删除代码
- ///这里创建了一个 isolate 但是非运行的
- auto isolate = CreateRootIsolate(settings, //
- isolate_snapshot, //
- task_runners, //
- std::move(platform_configuration), //
- snapshot_delegate, //
- hint_freed_delegate, //
- io_manager, //
- skia_unref_queue, //
- image_decoder, //
- advisory_script_uri, //
- advisory_script_entrypoint, //
- isolate_flags, //
- isolate_create_callback, //
- isolate_shutdown_callback //
- )
- .lock();
- ...删除部分代码 (主要是对 isolate的状态检查)
- //注意这个方法
- if (!isolate->RunFromLibrary(dart_entrypoint_library, //
- dart_entrypoint, //
- settings.dart_entrypoint_args //
- )) {
- FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
- return {};
- }
- if (settings.root_isolate_shutdown_callback) {
- isolate->AddIsolateShutdownCallback(
- settings.root_isolate_shutdown_callback);
- }
- shutdown_on_error.Release();
- return isolate;
- }
创建isolate后,进一步调用RunFromLibrary 这个方法:
tip:注意这个过程携带的参数。
- bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,
- std::optional<std::string> entrypoint,
- const std::vector<std::string>& args) {
- TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
- /// isolate 非准备状态,直接退出
- if (phase_ != Phase::Ready) {
- return false;
- }
- tonic::DartState::Scope scope(this);
- ...删除部分代码
- ///这里进一步调用了 InvokeMainEntrypoint方法
- if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
- return false;
- }
- ///设置 isolate为 运行状态
- phase_ = Phase::Running;
- return true;
- }
InvokeMainEntrypoint:
- [[nodiscard]] static bool InvokeMainEntrypoint(
- Dart_Handle user_entrypoint_function,
- Dart_Handle args) {
- ...删除部分代码
- ///这里,会通过DartInvokeField
- ///拉起我们的 main.dart中的main()方法并开始flutter的运行
- /// PS :这个入口点也可以自定义,不过很少用到
- if (tonic::LogIfError(tonic::DartInvokeField(
- Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
- {start_main_isolate_function, user_entrypoint_function, args}))) {
- FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
- return false;
- }
- return true;
- }
小结
到了这里,整个flutter的启动从平台到native所作的工作基本就简要的介绍完了。
本人也是刚开始对native进行了解,以进一步对flutter的运行原理有所了解,如果有错误之处,还请指出,谢谢。
用户评论