中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter在Android平臺上啟動時,Native層做了哪些工作

發布時間:2021-10-20 10:15:26 來源:億速云 閱讀:165 作者:iii 欄目:移動開發

這篇文章主要介紹“Flutter在Android平臺上啟動時,Native層做了哪些工作”,在日常操作中,相信很多人在Flutter在Android平臺上啟動時,Native層做了哪些工作問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Flutter在Android平臺上啟動時,Native層做了哪些工作”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

FlutterLoader

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 & onCreate

Flutter在Android平臺上啟動時,Native層做了哪些工作

這里需要提一下,目前你搜索FlutterActivity這個類,會發現有兩個:

android/FlutterActivity   這個是最新的 app/FlutterActivity    已過期

經過一系列調用,具體見這篇文章: Flutter&mdash;&mdash;在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中   ///以&lsquo;j&rsquo; 表示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

Flutter在Android平臺上啟動時,Native層做了哪些工作

此方法會調用 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;   }  ///創建一個 &lsquo;運行&rsquo;的 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層做了哪些工作”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乌拉特中旗| 赤峰市| 霍林郭勒市| 离岛区| 舟山市| 西丰县| 泰来县| 肥乡县| 阜康市| 南岸区| 永济市| 夏河县| 长宁区| 格尔木市| 湖南省| 泗阳县| 华亭县| 芦溪县| 织金县| 封开县| 孙吴县| 松溪县| 衡阳市| 吴川市| 潜江市| 大渡口区| 洛南县| 佛坪县| 钟山县| 田东县| 宁都县| 鹤岗市| 新晃| 蓬溪县| 边坝县| 确山县| 广宗县| 遵义市| 丹阳市| 乌鲁木齐县| 麟游县|