千家信息网

Flutter在Android平台上启动时,Native层做了哪些工作

发表于:2024-12-01 作者:千家信息网编辑
千家信息网最后更新 2024年12月01日,这篇文章主要介绍"Flutter在Android平台上启动时,Native层做了哪些工作",在日常操作中,相信很多人在Flutter在Android平台上启动时,Native层做了哪些工作问题上存在疑
千家信息网最后更新 2024年12月01日Flutter在Android平台上启动时,Native层做了哪些工作

这篇文章主要介绍"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 initTask = new Callable() {                   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 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(&Init),       },       {           .name = "nativePrefetchDefaultFontManager",           .signature = "()V",           .fnPtr = reinterpret_cast(&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 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(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 jni_facade =       std::make_shared(java_object);       ///主要就是初始化一个 shell holder   auto shell_holder = std::make_unique(       FlutterMain::Get().GetSettings(), jni_facade, is_background_view);   if (shell_holder->IsValid()) {     return reinterpret_cast(shell_holder.release());   } else {     return 0;   } }

我们来看一下AndroidShellHolder.cc的实现

AndroidShellHolder & gpu/ui/io线程的创建

它有一个100多行的构造函数:

AndroidShellHolder::AndroidShellHolder(     flutter::Settings settings,     std::shared_ptr 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(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 weak_platform_view;   Shell::CreateCallback on_create_platform_view =       [is_background_view, &jni_facade, &weak_platform_view](Shell& shell) {         std::unique_ptr platform_view_android;         if (is_background_view) {           ...走下面         } else {         ///初始化了一个PlatformViewAndroid           platform_view_android = std::make_unique(               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 on_create_rasterizer = [](Shell& shell) {     return std::make_unique(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 gpu_runner;   fml::RefPtr ui_runner;   fml::RefPtr io_runner;   fml::RefPtr 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::Create(     TaskRunners task_runners,     const PlatformData platform_data,     Settings settings,     Shell::CreateCallback on_create_platform_view,     Shell::CreateCallback 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 vm_snapshot,                             fml::RefPtr 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();   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::CreateShellOnPlatformThread(     DartVMRef vm,     TaskRunners task_runners,     const PlatformData platform_data,     Settings settings,     fml::RefPtr isolate_snapshot,     const Shell::CreateCallback& on_create_platform_view,     const Shell::CreateCallback& on_create_rasterizer) {        ...     ///创建对象   auto shell =       std::unique_ptr(new Shell(std::move(vm), task_runners, settings));    // 创建rasterizer :工作在gpu线程   // 这里要说一下,gpu线程还是在cpu上的,只是这个线程叫gpu 而已   std::promise> rasterizer_promise;   auto rasterizer_future = rasterizer_promise.get_future();   std::promise> 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(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(             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> 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(*shell, task_runners,                                                    std::move(vsync_waiter));          engine_promise.set_value(std::make_unique(             *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 isolate_snapshot,                TaskRunners task_runners,                const PlatformData platform_data,                Settings settings,                std::unique_ptr animator,                fml::WeakPtr io_manager,                fml::RefPtr unref_queue,                fml::WeakPtr snapshot_delegate)     : Engine(delegate,              dispatcher_maker,              vm.GetConcurrentWorkerTaskRunner(),              task_runners,              settings,              std::move(animator),              io_manager,              nullptr) {   runtime_controller_ = std::make_unique(       *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& 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 dart_entrypoint,     std::optional dart_entrypoint_library,     std::unique_ptr 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(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::CreateRunningRootIsolate(     const Settings& settings,     fml::RefPtr isolate_snapshot,     TaskRunners task_runners,     std::unique_ptr platform_configuration,     fml::WeakPtr snapshot_delegate,     fml::WeakPtr hint_freed_delegate,     fml::WeakPtr io_manager,     fml::RefPtr skia_unref_queue,     fml::WeakPtr 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 dart_entrypoint,     std::optional dart_entrypoint_library,     std::unique_ptr 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 library_name,                                  std::optional entrypoint,                                  const std::vector& 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层做了哪些工作"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0