美文网首页Android技术知识
Flutter在Android平台上启动时,Native层做了什

Flutter在Android平台上启动时,Native层做了什

作者: Android开发工作者 | 来源:发表于2021-01-20 19:59 被阅读0次

    前言

    接上一篇 [Flutter——在Android平台上的启动流程浅析]

    我们来看看穿插在其中的native层都做了什么。

    由于代码较多,我会将说明以注释的形式写在代码里,并删除非必要代码
    复制代码
    

    FlutterLoader

    在flutterLoader中的这个startInitialization()方法中:

        public void startInitialization(@NonNull Context applicationContext, @NonNull FlutterLoader.Settings settings) {
            if (this.settings == null) {
                if (Looper.myLooper() != Looper.getMainLooper()) {
                    throw new IllegalStateException("startInitialization must be called on the main thread");
                } else {
                    ....
                    Callable<FlutterLoader.InitResult> initTask = new Callable<FlutterLoader.InitResult>() {
                        public FlutterLoader.InitResult call() {
                            ....
                            ///这里是在子线程执行的
                            System.loadLibrary("flutter");
                            ....
    
                            return new FlutterLoader.InitResult(PathUtils.getFilesDir(appContext), PathUtils.getCacheDirectory(appContext), PathUtils.getDataDirectory(appContext));
                        }
                    };
                    this.initResultFuture = Executors.newSingleThreadExecutor().submit(initTask);
                }
            }
        }
    复制代码
    

    System.loadLibrary("flutter");并不是简单地加载flutter框架代码,它最终会进入native中的JNI_OnLoad方法:

    // This is called by the VM when the shared library is first loaded.
    JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
      // 初始化 JVM (只是将虚拟机进行一个保存)
      // 之后关联到当前线程上
      fml::jni::InitJavaVM(vm);
    
      JNIEnv* env = fml::jni::AttachCurrentThread();
      bool result = false;
    
      // 注册 FlutterMain.
      result = flutter::FlutterMain::Register(env);
      FML_CHECK(result);
    
      // 注册 PlatformView
      // 这里会注册大量的方法,使c++和java可以互相调用
      result = flutter::PlatformViewAndroid::Register(env);
      FML_CHECK(result);
    
      // 注册 VSyncWaiter.
      // 这里将java的VSyncWaiter类中的方法与
      // native中的VsyncWaiterAndroid的映射,便可以互相调用
      result = flutter::VsyncWaiterAndroid::Register(env);
      FML_CHECK(result);
    
      return JNI_VERSION_1_4;
    }
    复制代码
    
    tip:PlatformViewAndroid路径为:engine/shell/platform/android
    有兴趣的话,可以看看
    复制代码
    

    整体来看,这里主要是保存了jvm,同时对c++和java的方法进行了映射以便双方可以互相调用。

    至此FlutterApplication中所拉起的native代码就简单概括完了,我们接着FlutterActivity中所调用native代码。

    FlutterActivity & onCreate

    image

    这里需要提一下,目前你搜索FlutterActivity这个类,会发现有两个:

    android/FlutterActivity   这个是最新的
    app/FlutterActivity    已过期
    复制代码
    

    (https://juejin.cn/post/6913773851532853255),

    会初始化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<void*>(&Init),便会拉起它的FlutterMain::Init方法。

    void FlutterMain::Init(JNIEnv* env,
                           jclass clazz,
                           jobject context,
                           jobjectArray jargs,
                           jstring kernelPath,
                           jstring appStoragePath,
                           jstring engineCachesPath,
                           jlong initTimeMillis) {
      std::vector<std::string> args;
      ///tag
      args.push_back("flutter");
      ///将上面我们收集的那些路径信息保存到 args中
      ///以‘j’ 表示java传过来的。
      for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
        args.push_back(std::move(arg));
      }
      auto command_line = fml::CommandLineFromIterators(args.begin(), args.end());
    
      auto settings = SettingsFromCommandLine(command_line);
      ///engine启动时间
      int64_t init_time_micros = initTimeMillis * 1000;
      settings.engine_start_timestamp =
          std::chrono::microseconds(Dart_TimelineGetMicros() - init_time_micros);
    
      // Restore the callback cache.
      // TODO(chinmaygarde): Route all cache file access through FML and remove this
      // setter.
      flutter::DartCallbackCache::SetCachePath(
          fml::jni::JavaStringToString(env, appStoragePath));
     ///初始化缓存路径
      fml::paths::InitializeAndroidCachesPath(
          fml::jni::JavaStringToString(env, engineCachesPath));
      ///加载缓存
      flutter::DartCallbackCache::LoadCacheFromDisk();
    
      if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) {
        // Check to see if the appropriate kernel files are present and configure
        // settings accordingly.
        auto application_kernel_path =
            fml::jni::JavaStringToString(env, kernelPath);
    
        if (fml::IsFile(application_kernel_path)) {
          settings.application_kernel_asset = application_kernel_path;
        }
      }
    
      settings.task_observer_add = [](intptr_t key, fml::closure callback) {
        fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
      };
    
      settings.task_observer_remove = [](intptr_t key) {
        fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
      };
    
    #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
      // There are no ownership concerns here as all mappings are owned by the
      // embedder and not the engine.
      auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
        return [mapping, size]() {
          return std::make_unique<fml::NonOwnedMapping>(mapping, size);
        };
      };
    
      settings.dart_library_sources_kernel =
          make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
    #endif  // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
    
      // Not thread safe. Will be removed when FlutterMain is refactored to no
      // longer be a singleton.
      g_flutter_main.reset(new FlutterMain(std::move(settings)));
    
      g_flutter_main->SetupObservatoryUriCallback(env);
    }
    复制代码
    

    以上主要是对java传过来的数据进行保存,至此由flutterLoader.ensureInitializationComplete所引起的native执行完毕, 在其后面会执行attachToJni()。

    FlutterActivity& attachToJni()

    attachToJni()最终会调用flutterJNI.attachToNative(false):

    ///这步完成后,android便可以与engine通信了
      @UiThread
      public void attachToNative(boolean isBackgroundView) {
        ensureRunningOnMainThread();
        ensureNotAttachedToNative();
        nativePlatformViewId = nativeAttach(this, isBackgroundView);
      }
    
      private native long nativeAttach(@NonNull FlutterJNI flutterJNI, boolean isBackgroundView);
    复制代码
    

    此方法会调用native的:

    static jlong AttachJNI(JNIEnv* env,
                           jclass clazz,
                           jobject flutterJNI,
                           jboolean is_background_view) {
      fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
      std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
          std::make_shared<PlatformViewAndroidJNIImpl>(java_object);
          ///主要就是初始化一个 shell holder
      auto shell_holder = std::make_unique<AndroidShellHolder>(
          FlutterMain::Get().GetSettings(), jni_facade, is_background_view);
      if (shell_holder->IsValid()) {
        return reinterpret_cast<jlong>(shell_holder.release());
      } else {
        return 0;
      }
    }
    复制代码
    

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

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

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

    AndroidShellHolder::AndroidShellHolder(
        flutter::Settings settings,
        std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
        bool is_background_view)
        : settings_(std::move(settings)), jni_facade_(jni_facade) {
      static size_t shell_count = 1;
      auto thread_label = std::to_string(shell_count++);
    
      FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) ==
                0);
      ///这里我们传递的是false
      if (is_background_view) {
        thread_host_ = {thread_label, ThreadHost::Type::UI};
      } else {
      /// 会创建三个线程 分别是 UI\GPU\IO
        thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
                                          ThreadHost::Type::IO};
      }
    
      // Detach from JNI when the UI and raster threads exit.
      // UI和raster线程退出时,与JNI分离
      // raster就是gpu线程,它将我们的绘制指令转为gpu指令
      auto jni_exit_task([key = thread_destruct_key_]() {
        FML_CHECK(pthread_setspecific(key, reinterpret_cast<void*>(1)) == 0);
      });
      thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task);
      if (!is_background_view) {
        thread_host_.raster_thread->GetTaskRunner()->PostTask(jni_exit_task);
      }
    
      fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
      Shell::CreateCallback<PlatformView> on_create_platform_view =
          [is_background_view, &jni_facade, &weak_platform_view](Shell& shell) {
            std::unique_ptr<PlatformViewAndroid> platform_view_android;
            if (is_background_view) {
              ...走下面
            } else {
            ///初始化了一个PlatformViewAndroid
              platform_view_android = std::make_unique<PlatformViewAndroid>(
                  shell,                   // delegate
                  shell.GetTaskRunners(),  // task runners
                  jni_facade,              // JNI interop
                  shell.GetSettings()
                      .enable_software_rendering  // use software rendering
              );
            }
            weak_platform_view = platform_view_android->GetWeakPtr();
            shell.OnDisplayUpdates(DisplayUpdateType::kStartup,
                                   {Display(jni_facade->GetDisplayRefreshRate())});
            return platform_view_android;
          };
    
      Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell);
      };
    
      // The current thread will be used as the platform thread. Ensure that the
      // message loop is initialized.
      // 初始化native的 message loop
      // gpu/ui/io它们也有各自的 msg loop
      fml::MessageLoop::EnsureInitializedForCurrentThread();
      ///初始化对应线程的task runner
      /// 这样我们便可以向指定线程post 任务
      fml::RefPtr<fml::TaskRunner> gpu_runner;
      fml::RefPtr<fml::TaskRunner> ui_runner;
      fml::RefPtr<fml::TaskRunner> io_runner;
      fml::RefPtr<fml::TaskRunner> platform_runner =
          fml::MessageLoop::GetCurrent().GetTaskRunner();
      if (is_background_view) {
        auto single_task_runner = thread_host_.ui_thread->GetTaskRunner();
        gpu_runner = single_task_runner;
        ui_runner = single_task_runner;
        io_runner = single_task_runner;
      } else {
        gpu_runner = thread_host_.raster_thread->GetTaskRunner();
        ui_runner = thread_host_.ui_thread->GetTaskRunner();
        io_runner = thread_host_.io_thread->GetTaskRunner();
      }
    
      flutter::TaskRunners task_runners(thread_label,     // label
                                        platform_runner,  // platform
                                        gpu_runner,       // raster
                                        ui_runner,        // ui
                                        io_runner         // io
      );
      ///提高ui 和 gpu线程等级
      ///线程值 越小 等级越高
      task_runners.GetRasterTaskRunner()->PostTask([]() {
        // Android describes -8 as "most important display threads, for
        // compositing the screen and retrieving input events". Conservatively
        // set the raster thread to slightly lower priority than it.
        if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
          // Defensive fallback. Depending on the OEM, it may not be possible
          // to set priority to -5.
          if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
            FML_LOG(ERROR) << "Failed to set GPU task runner priority";
          }
        }
      });
      task_runners.GetUITaskRunner()->PostTask([]() {
        if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
          FML_LOG(ERROR) << "Failed to set UI task runner priority";
        }
      });
        ///创建shell
      shell_ =
          Shell::Create(task_runners,              // task runners
                        GetDefaultPlatformData(),  // window data
                        settings_,                 // settings
                        on_create_platform_view,   // platform view create callback
                        on_create_rasterizer       // rasterizer create callback
          );
    
      platform_view_ = weak_platform_view;
      FML_DCHECK(platform_view_);
      is_valid_ = shell_ != nullptr;
    }
    复制代码
    

    Shell

    我们接着看一下 shell_的创建:

    std::unique_ptr<Shell> Shell::Create(
        TaskRunners task_runners,
        const PlatformData platform_data,
        Settings settings,
        Shell::CreateCallback<PlatformView> on_create_platform_view,
        Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
      PerformInitializationTasks(settings);
      PersistentCache::SetCacheSkSL(settings.cache_sksl);
    
      TRACE_EVENT0("flutter", "Shell::Create");
      ///创建虚拟机
      auto vm = DartVMRef::Create(settings);
      FML_CHECK(vm) << "Must be able to initialize the VM.";
    
      auto vm_data = vm->GetVMData();
    
      return Shell::Create(std::move(task_runners),        //
                           std::move(platform_data),       //
                           std::move(settings),            //
                           vm_data->GetIsolateSnapshot(),  // isolate snapshot
                           on_create_platform_view,        //
                           on_create_rasterizer,           //
                           std::move(vm)                   //
      );
    }
    复制代码
    

    DartVMRef::Create

    DartVMRef DartVMRef::Create(Settings settings,
                                fml::RefPtr<DartSnapshot> vm_snapshot,
                                fml::RefPtr<DartSnapshot> isolate_snapshot) {
      std::scoped_lock lifecycle_lock(gVMMutex);
    
      ...删除一些代码
    
      //这里对已有的虚拟机进行复用
      if (auto vm = gVM.lock()) {
        FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was "
                             "already running. Ignoring arguments for current VM "
                             "create call and reusing the old VM.";
        // There was already a running VM in the process,
        return DartVMRef{std::move(vm)};
      }
    
      ...删除一些代码
    
      //如果没有,就重新创建一个虚拟机
      auto isolate_name_server = std::make_shared<IsolateNameServer>();
      auto vm = DartVM::Create(std::move(settings),          //
                               std::move(vm_snapshot),       //
                               std::move(isolate_snapshot),  //
                               isolate_name_server           //
      );
    
      ...删除一些代码
    
      return DartVMRef{std::move(vm)};
    }
    复制代码
    

    我们继续看shell的创建,最终会调用CreateShellOnPlatformThread。

    Shell & CreateShellOnPlatformThread

    std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
        DartVMRef vm,
        TaskRunners task_runners,
        const PlatformData platform_data,
        Settings settings,
        fml::RefPtr<const DartSnapshot> isolate_snapshot,
        const Shell::CreateCallback<PlatformView>& on_create_platform_view,
        const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
    
      ...
        ///创建对象
      auto shell =
          std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
    
      // 创建rasterizer :工作在gpu线程
      // 这里要说一下,gpu线程还是在cpu上的,只是这个线程叫gpu 而已
      std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
      auto rasterizer_future = rasterizer_promise.get_future();
      std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise;
      auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
      fml::TaskRunner::RunNowOrPostTask(
          task_runners.GetRasterTaskRunner(), [&rasterizer_promise,  //
                                               &snapshot_delegate_promise,
                                               on_create_rasterizer,  //
                                               shell = shell.get()    //
      ]() {
            TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
            std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
            snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
            rasterizer_promise.set_value(std::move(rasterizer));
          });
    
      // 在当前线程(platform thread)创建platform view.
      auto platform_view = on_create_platform_view(*shell.get());
      if (!platform_view || !platform_view->GetWeakPtr()) {
        return nullptr;
      }
    
      // Ask the platform view for the vsync waiter. This will be used by the engine
      // to create the animator.
      auto vsync_waiter = platform_view->CreateVSyncWaiter();
      if (!vsync_waiter) {
        return nullptr;
      }
    
      ...删除部分代码...
    
      ///通过向 io线程post task 来创建 io manager
      fml::TaskRunner::RunNowOrPostTask(
          io_task_runner,
          [&io_manager_promise,                                               //
           &weak_io_manager_promise,                                          //
           &unref_queue_promise,                                              //
           platform_view = platform_view->GetWeakPtr(),                       //
           io_task_runner,                                                    //
           is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch()  //
      ]() {
            TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
            auto io_manager = std::make_unique<ShellIOManager>(
                platform_view.getUnsafe()->CreateResourceContext(),
                is_backgrounded_sync_switch, io_task_runner);
            weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
            unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
            io_manager_promise.set_value(std::move(io_manager));
          });
    
      // Send dispatcher_maker to the engine constructor because shell won't have
      // platform_view set until Shell::Setup is called later.
      auto dispatcher_maker = platform_view->GetDispatcherMaker();
    
      // 在ui线程创建engine
      // 这里的engine指针被跨线程使用
      std::promise<std::unique_ptr<Engine>> engine_promise;
      auto engine_future = engine_promise.get_future();
      fml::TaskRunner::RunNowOrPostTask(
          shell->GetTaskRunners().GetUITaskRunner(),
          fml::MakeCopyable([&engine_promise,                                 //
                             shell = shell.get(),                             //
                             &dispatcher_maker,                               //
                             &platform_data,                                  //
                             isolate_snapshot = std::move(isolate_snapshot),  //
                             vsync_waiter = std::move(vsync_waiter),          //
                             &weak_io_manager_future,                         //
                             &snapshot_delegate_future,                       //
                             &unref_queue_future                              //
      ]() mutable {
            TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
            const auto& task_runners = shell->GetTaskRunners();
    
            // 创建animator(ui线程)
            auto animator = std::make_unique<Animator>(*shell, task_runners,
                                                       std::move(vsync_waiter));
    
            engine_promise.set_value(std::make_unique<Engine>(
                *shell,                         //
                dispatcher_maker,               //
                *shell->GetDartVM(),            //
                std::move(isolate_snapshot),    //
                task_runners,                   //
                platform_data,                  //
                shell->GetSettings(),           //
                std::move(animator),            //
                weak_io_manager_future.get(),   //
                unref_queue_future.get(),       //
                snapshot_delegate_future.get()  //
                ));
          }));
    
      if (!shell->Setup(std::move(platform_view),  //
                        engine_future.get(),       //
                        rasterizer_future.get(),   //
                        io_manager_future.get())   //
      ) {
        return nullptr;
      }
    
      return shell;
    }
    复制代码
    

    由于代码太长,这里再汇总一下:

    shell初始化之后,还有分别在io/ui/gpu/platform线程创建以下对象:

    • rasterizer 在gpu线程工作,负责将绘制指令转为gpu指令

    • platform view 在当前线程(platform thread)

    • engine 和 animator 在ui线程工作

      flutter最终会通过animator向platformView 申请VSync信号

    接下来我们再看一下上面代码中对engine的初始化。

    Engine

    代码相对较少,但是连接的东西非常多:

    Engine::Engine(Delegate& delegate,
                   const PointerDataDispatcherMaker& dispatcher_maker,
                   DartVM& vm,
                   fml::RefPtr<const DartSnapshot> isolate_snapshot,
                   TaskRunners task_runners,
                   const PlatformData platform_data,
                   Settings settings,
                   std::unique_ptr<Animator> animator,
                   fml::WeakPtr<IOManager> io_manager,
                   fml::RefPtr<SkiaUnrefQueue> unref_queue,
                   fml::WeakPtr<SnapshotDelegate> snapshot_delegate)
        : Engine(delegate,
                 dispatcher_maker,
                 vm.GetConcurrentWorkerTaskRunner(),
                 task_runners,
                 settings,
                 std::move(animator),
                 io_manager,
                 nullptr) {
      runtime_controller_ = std::make_unique<RuntimeController>(
          *this,                                 // runtime delegate
          &vm,                                   // VM
          std::move(isolate_snapshot),           // isolate snapshot
          task_runners_,                         // task runners
          std::move(snapshot_delegate),          // snapshot delegate
          GetWeakPtr(),                          // hint freed delegate
          std::move(io_manager),                 // io manager
          std::move(unref_queue),                // Skia unref queue
          image_decoder_.GetWeakPtr(),           // image decoder
          settings_.advisory_script_uri,         // advisory script uri
          settings_.advisory_script_entrypoint,  // advisory script entrypoint
          settings_.idle_notification_callback,  // idle notification callback
          platform_data,                         // platform data
          settings_.isolate_create_callback,     // isolate create callback
          settings_.isolate_shutdown_callback,   // isolate shutdown callback
          settings_.persistent_isolate_data      // persistent isolate data
      );
    }
    复制代码
    

    就是创建了一个runtime_controller_ ,你可以将runtime controller 看做native、platform和flutter的一个纽带。

    小结

    经过上面一系列的代码,可能有点晕,概括来讲Flutter Activity在注册flutterMain过程中会创建初始化shell,而在这个初始化的过程中,我们分别会创建三个线程,算上当前线程的话,就是4个:

    • platform 线程(当前线程)
    • ui 线程
    • gpu 线程
    • io 线程

    并初始化一系列重要对象。

    好的,我们再回到主线,onCreate()已经过了,下面我们可以看一下onStart()生命周期:

    FlutterActivity & onStart

    此方法会调用 delegate.onStart(); 并最终调用FlutterJNI的native方法:

      private native void nativeRunBundleAndSnapshotFromLibrary(
          long nativePlatformViewId,
          @NonNull String bundlePath,
          @Nullable String entrypointFunctionName,
          @Nullable String pathToEntrypointFunction,
          @NonNull AssetManager manager);
    复制代码
    

    从这里开始,其终点就是执行dart的代码。

    Launch

    接着我们看一下native方法:

    (位置在platform_view_android_jni_impl.cc)

    static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
                                                jobject jcaller,
                                                jlong shell_holder,
                                                jstring jBundlePath,
                                                jstring jEntrypoint,
                                                jstring jLibraryUrl,
                                                jobject jAssetManager) {
      ...删除部分代码
      ///这里主要是根据参数,生成一个config 并用于启动
      /// 我们的 默认启动入口 'main()'就在这个config里
    
      ANDROID_SHELL_HOLDER->Launch(std::move(config));
    }
    复制代码
    

    我们接着看Launch(std::move(config));方法:

    void AndroidShellHolder::Launch(RunConfiguration config) {
      if (!IsValid()) {
        return;
      }
    
      shell_->RunEngine(std::move(config));
    }
    复制代码
    

    又调用了 run engine 方法:

    void Shell::RunEngine(
        RunConfiguration run_configuration,
        const std::function<void(Engine::RunStatus)>& result_callback) {
      ...删除一些代码
    
    ///向 ui线程post了一个任务
      fml::TaskRunner::RunNowOrPostTask(
          task_runners_.GetUITaskRunner(),
          fml::MakeCopyable(
              [run_configuration = std::move(run_configuration),
               weak_engine = weak_engine_, result]() mutable {
                if (!weak_engine) {
                  FML_LOG(ERROR)
                      << "Could not launch engine with configuration - no engine.";
                  result(Engine::RunStatus::Failure);
                  return;
                }
                ///调用engine的run方法
                auto run_result = weak_engine->Run(std::move(run_configuration));
                if (run_result == flutter::Engine::RunStatus::Failure) {
                  FML_LOG(ERROR) << "Could not launch engine with configuration.";
                }
                result(run_result);
              }));
    }
    复制代码
    

    Engin.run()

    Engine::RunStatus Engine::Run(RunConfiguration configuration) {
      if (!configuration.IsValid()) {
        FML_LOG(ERROR) << "Engine run configuration was invalid.";
        return RunStatus::Failure;
      }
     ///获取要执行的 dart代码入口点
     ///这里就是 main方法 from mian.dart
      last_entry_point_ = configuration.GetEntrypoint();
      last_entry_point_library_ = configuration.GetEntrypointLibrary();
    
      ....
    
      ///调用了LaunchRootIsolate方法
      if (!runtime_controller_->LaunchRootIsolate(
              settings_,                                 //
              configuration.GetEntrypoint(),             //
              configuration.GetEntrypointLibrary(),      //
              configuration.TakeIsolateConfiguration())  //
      ) {
        return RunStatus::Failure;
      }
    
      ...删除部分代码
    
      return Engine::RunStatus::Success;
    }
    复制代码
    

    LaunchRootIsolate

    bool RuntimeController::LaunchRootIsolate(
        const Settings& settings,
        std::optional<std::string> dart_entrypoint,
        std::optional<std::string> dart_entrypoint_library,
        std::unique_ptr<IsolateConfiguration> isolate_configuration) {
      if (root_isolate_.lock()) {
        FML_LOG(ERROR) << "Root isolate was already running.";
        return false;
      }
     ///创建一个 ‘运行’的 root isolate
      auto strong_root_isolate =
          DartIsolate::CreateRunningRootIsolate(
              settings,                                       // 配置
              isolate_snapshot_,                              // 快照
              task_runners_,                                  // 
              std::make_unique<PlatformConfiguration>(this),  // 平台配置
              snapshot_delegate_,                             //
              hint_freed_delegate_,                           //
              io_manager_,                                    // io管理运行在Io线程
              unref_queue_,                                   // 
              image_decoder_,                                 // 图片解码
              advisory_script_uri_,                           //
              advisory_script_entrypoint_,                    //
              DartIsolate::Flags{},                           //
              isolate_create_callback_,                       //
              isolate_shutdown_callback_,                     //
              dart_entrypoint,                                // 入口 方法(main.dart)
              dart_entrypoint_library,                        // 入口库
              std::move(isolate_configuration)                //
              )
              .lock();
    
      ...删除部分代码
    
      return true;
    }
    复制代码
    

    我们看一下DartIsolate的CreateRunningRootIsolate方法

    DartIsolate::CreateRunningRootIsolate

    std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
        const Settings& settings,
        fml::RefPtr<const DartSnapshot> isolate_snapshot,
        TaskRunners task_runners,
        std::unique_ptr<PlatformConfiguration> platform_configuration,
        fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
        fml::WeakPtr<HintFreedDelegate> hint_freed_delegate,
        fml::WeakPtr<IOManager> io_manager,
        fml::RefPtr<SkiaUnrefQueue> skia_unref_queue,
        fml::WeakPtr<ImageDecoder> image_decoder,
        std::string advisory_script_uri,
        std::string advisory_script_entrypoint,
        Flags isolate_flags,
        const fml::closure& isolate_create_callback,
        const fml::closure& isolate_shutdown_callback,
        std::optional<std::string> dart_entrypoint,
        std::optional<std::string> dart_entrypoint_library,
        std::unique_ptr<IsolateConfiguration> isolate_configration) {
    
     ...删除代码
    
     ///这里创建了一个 isolate 但是非运行的
      auto isolate = CreateRootIsolate(settings,                           //
                                       isolate_snapshot,                   //
                                       task_runners,                       //
                                       std::move(platform_configuration),  //
                                       snapshot_delegate,                  //
                                       hint_freed_delegate,                //
                                       io_manager,                         //
                                       skia_unref_queue,                   //
                                       image_decoder,                      //
                                       advisory_script_uri,                //
                                       advisory_script_entrypoint,         //
                                       isolate_flags,                      //
                                       isolate_create_callback,            //
                                       isolate_shutdown_callback           //
                                       )
                         .lock();
    
      ...删除部分代码 (主要是对 isolate的状态检查)
    
     //注意这个方法
      if (!isolate->RunFromLibrary(dart_entrypoint_library,       //
                                   dart_entrypoint,               //
                                   settings.dart_entrypoint_args  //
                                   )) {
        FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
        return {};
      }
    
      if (settings.root_isolate_shutdown_callback) {
        isolate->AddIsolateShutdownCallback(
            settings.root_isolate_shutdown_callback);
      }
    
      shutdown_on_error.Release();
    
      return isolate;
    }
    复制代码
    

    创建isolate后,进一步调用RunFromLibrary 这个方法:

    tip:注意这个过程携带的参数。

    bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,
                                     std::optional<std::string> entrypoint,
                                     const std::vector<std::string>& args) {
      TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
      /// isolate 非准备状态,直接退出
      if (phase_ != Phase::Ready) {
        return false;
      }
    
      tonic::DartState::Scope scope(this);
    
     ...删除部分代码
    
      ///这里进一步调用了 InvokeMainEntrypoint方法
      if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
        return false;
      }
     ///设置 isolate为 运行状态
      phase_ = Phase::Running;
    
      return true;
    }
    复制代码
    

    InvokeMainEntrypoint:

    [[nodiscard]] static bool InvokeMainEntrypoint(
        Dart_Handle user_entrypoint_function,
        Dart_Handle args) {
      ...删除部分代码
      ///这里,会通过DartInvokeField
      ///拉起我们的 main.dart中的main()方法并开始flutter的运行
      /// PS :这个入口点也可以自定义,不过很少用到
      if (tonic::LogIfError(tonic::DartInvokeField(
              Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
              {start_main_isolate_function, user_entrypoint_function, args}))) {
        FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
        return false;
      }
    
      return true;
    }
    复制代码
    

    小结

    到了这里,整个flutter的启动从平台到native所作的工作基本就简要的介绍完了。

    本人也是刚开始对native进行了解,以进一步对flutter的运行原理有所了解,如果有错误之处,还请指出,谢谢。

    作者:吉哈达
    链接:https://juejin.cn/post/6918657250353479694
    来源:掘金

    相关文章

      网友评论

        本文标题:Flutter在Android平台上启动时,Native层做了什

        本文链接:https://www.haomeiwen.com/subject/hugqzktx.html