这篇文章主要介绍“Flutter在Android平台上启动时,Native层做了哪些工作”,在日常操作中,相信很多人在Flutter在Android平台上启动时,Native层做了哪些工作问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Flutter在Android平台上启动时,Native层做了哪些工作”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
在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这个类,会发现有两个:
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()生命周期:
此方法会调用 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在Android平台上启动时,Native层做了哪些工作”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。