Flutter-Android-Embedder启动流程

本文详细解析了Flutter在Android平台上的Embedder启动流程,从FlutterApplication的onCreate开始,经过FlutterLoader的初始化,到FlutterActivity的各个生命周期方法,特别是FlutterActivityAndFragmentDelegate的创建与初始化,最后阐述了如何启动dart虚拟机并通知Flutter应用的状态变化。
摘要由CSDN通过智能技术生成

概述

Flutter的启动包括Embedder、Engine、Framework三部分,本文仅描述Android平台的Embdder模块的启动流程。Flutter通常通过启动一个FlutterActivity启动,纯Flutter App则通过FlutterApplication启动。本文以后一种情况为例分析。

FlutterApplication#onCreate

// io/flutter/app/FlutterApplication.java

  @Override
  @CallSuper
  public void onCreate() {
    super.onCreate();
    FlutterInjector.instance().flutterLoader().startInitialization(this);
  }

实际是调用FlutterLoader#startInitialization进行初始化。

FlutterLoader#startInitialization


  public void startInitialization(@NonNull Context applicationContext) {
    startInitialization(applicationContext, new Settings());
  }

  public void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) {
    if (this.settings != null) {
      return;
    }
    if (Looper.myLooper() != Looper.getMainLooper()) {
      throw new IllegalStateException("startInitialization must be called on the main thread");
    }

    final Context appContext = applicationContext.getApplicationContext();

    this.settings = settings;

    initStartTimestampMillis = SystemClock.uptimeMillis();
    flutterApplicationInfo = ApplicationInfoLoader.load(appContext);
    VsyncWaiter.getInstance((WindowManager) appContext.getSystemService(Context.WINDOW_SERVICE))
        .init();

    // Use a background thread for initialization tasks that require disk access.
    Callable<InitResult> initTask =
        new Callable<InitResult>() {
          @Override
          public InitResult call() {
            ResourceExtractor resourceExtractor = initResources(appContext);

            if (FlutterInjector.instance().shouldLoadNative()) {
              System.loadLibrary("flutter");
            }

            // Prefetch the default font manager as soon as possible on a background thread.
            // It helps to reduce time cost of engine setup that blocks the platform thread.
            Executors.newSingleThreadExecutor()
                .execute(
                    new Runnable() {
                      @Override
                      public void run() {
                        FlutterJNI.nativePrefetchDefaultFontManager();
                      }
                    });

            if (resourceExtractor != null) {
              resourceExtractor.waitForCompletion();
            }

            return new InitResult(
                PathUtils.getFilesDir(appContext),
                PathUtils.getCacheDirectory(appContext),
                PathUtils.getDataDirectory(appContext));
          }
        };
    initResultFuture = Executors.newSingleThreadExecutor().submit(initTask);
  }

主要做了以下几件事:

  1. 检查是否在主线程

  2. 注册Vsync信号监听

  3. 启动一个异步任务,执行以下操作:

    1. 加载flutter engine

    2. 异步初始化字体管理器

    3. 加载asset目录下的资源

以上是Application会执行的操作,接着一般会进入一个FlutterActivity,那么依次查看其回调。

FlutterActivity#onCreate

// io/flutter/embedding/android/FlutterActivity.java

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    switchLaunchThemeForNormalTheme();

    super.onCreate(savedInstanceState);

    lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);

    delegate = new FlutterActivityAndFragmentDelegate(this);
    delegate.onAttach(this);
    delegate.onActivityCreated(savedInstanceState);

    configureWindowForTransparency();
    setContentView(createFlutterView());
    configureStatusBarForFullscreenFlutterExperience();
  }

主要做了以下几件事:

  1. 从Splash切换成真正要显示的View

  2. 创建一个delegate,并触发对应回调

  3. 配置相关的窗口属性

  4. 创建一个新的FlutterView,作为Activity的ContentView

FlutterActivityAndFragmentDelegate#onAttach

  void onAttach(@NonNull Context context) {
    ensureAlive();
    if (flutterEngine == null) {
      setupFlutterEngine();
    }

    if (h
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值