Flutter源码阅读分析:引擎初始化与启动

引擎初始化与启动


本文也发布于本人的知乎专栏:https://zhuanlan.zhihu.com/p/394560540

0. 前言

Flutter是当前比较火热的前端开发框架,正好我最近也在做和Flutter引擎相关的工作,就顺手研究一下Flutter的源码。
源码主要分为两部分:

  • Engine,是可供Flutter宿主应用提供的一个可移植运行时。Engine实现了Flutter的核心库,包括动画、图形、文件、网络I/O、访问支持、插件架构和Dart的运行时、编译工具链;
  • Flutter Framework,大部分的Flutter开发者主要通过Flutter Framework交互。Framework提供了一个现代的、可交互的框架,以及一个丰富的平台、布局、基础部件的集合。

Flutter官方源码下载路径:
engine: https://github.com/flutter/engine
flutter framework: https://github.com/flutter/flutter

本文主要分析引擎的初始化流程和启动流程。


1. 初始化流程

1.1 Android平台适配层

众所周知,Android应用的入口基本都是Activity,那么我们就先从Flutter的Activity开始着手分析。

1.1.1 FlutterActivity

Engine中存在两个FlutterActivity(shell/platform/android/io/flutter/app/FlutterActivity.javashell/platform/android/io/flutter/embedding/android/FlutterActivity.java),其中在2020年5月13日的代码提交中,前一个FlutterActivity注释修改为废弃Activity基类。所以现在可用的Activity基类是后一个。
根据FlutterActivity的注释,我们可知:
FlutterActivity是将Flutter集成到Android应用中的最简单最直接的方式,用于显示一个全屏的Flutter UI。主要职责是:

  • 显示一个Android的lauch screen;
  • 显示Flutter的splash screen;
  • 设置状态栏;
  • 选择Dart执行应用包路径和入口点;
  • 选择Flutter的初始化路由;
  • 如果需要的话,渲染透明度;
  • 提供子类钩子,提供和配置FlutterEngine。

先从FlutterActivity定义看起:

public class FlutterActivity extends Activity
    implements FlutterActivityAndFragmentDelegate.Host, LifecycleOwner

FlutterActivity继承于ActivityFlutterActivityAndFragmentDelegate.Host接口是在FlutterActivityAndFragmentDelegateFlutterActivity持有类。

ActivityonCreate方法是入口关键方法,看一下FlutterActivityonCreate方法:

// ./shell/platform/android/io/flutter/embedding/android/FlutterActivity.java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
   
  switchLaunchThemeForNormalTheme(); // 设置主题

  super.onCreate(savedInstanceState);

  lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); // 设置Android生命周期

  delegate = new FlutterActivityAndFragmentDelegate(this); // [1]
  delegate.onAttach(this);
  delegate.onActivityCreated(savedInstanceState);

  configureWindowForTransparency(); // 设置背景透明模式
  setContentView(createFlutterView()); // [2]
  configureStatusBarForFullscreenFlutterExperience(); // 配置系统状态栏
}
  • [1] FlutterActivityAndFragmentDelegate类实现了FlutterActivityFlutterFragment之间相同的逻辑。
  • [2] 通过调用FlutterActivityAndFragmentDelegateonCreateView方法创建出FlutterView并将其添加到界面上。FlutterView用于在Android设备上显示Flutter UI。
1.1.2 FlutterActivityAndFragmentDelegate

下面就再分析一下FlutterActivityAndFragmentDelegate的源码逻辑:

// ./shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java
final class FlutterActivityAndFragmentDelegate {
   
  ...
  FlutterActivityAndFragmentDelegate(@NonNull Host host) {
   
    this.host = host; // 保存FlutterActivity对象
  }
  ...
  // [3]
  void onAttach(@NonNull Context context) {
   
    ...
    setupFlutterEngine(); // 创建FlutterEngine
    ...
  }
  ...
  // [4]
  @NonNull
  View onCreateView(
      LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
   
    ...
    // 创建FlutterSurfaceView,用于提供绘制Flutter UI的Surface
    FlutterSurfaceView flutterSurfaceView =
        new FlutterSurfaceView(
            host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent);
    ...
    flutterView = new FlutterView(host.getActivity(), flutterSurfaceView);
    ...
    flutterSplashView = new FlutterSplashView(host.getContext());
    ...
    flutterSplashView.displayFlutterViewWithSplash(flutterView, host.provideSplashScreen());
    flutterView.attachToFlutterEngine(flutterEngine);
    return 
  }
  ...
  return flutterSplashView;
}
  • [3] onAttach方法主要做了以下事情:1. 初始化Flutter系统;2. 获取或者创建一个FlutterEngine;3. 创建和配置PlatformPlugin;4. 将FlutterEngine附在Activity上;5. 通过HostconfigureFlutterEngine方法配置FlutterEngine
  • [4] 'onCreateView’方法主要做以下事情:1. 在View树中创建一个新的FlutterView;2. 在FlutterView中添加一个FlutterUiDisplayListener;3. 将FlutterEngine附着到FlutterView上;4. 返回这个新的View树。

在这里出现了两个比较重要的类,FlutterViewFlutterEngine

1.1.3 FlutterView

FlutterView的作用是将Flutter UI通过对应的FlutterEngine绘制后,显示在Android设备上。这里有两种渲染模式:surfacetexture
在一般情况,我们都使用surface模式,即将Flutter UI绘制在SurfaceView上,这种模式拥有最优的性能,缺点是无法置于两个其他Android View的z-index之间,同时也无法动画化或者进行变换。
下面我们看一下FlutterView的源码实现:

// ./shell/platform/android/io/flutter/embedding/android/FlutterView.java
public class FlutterView extends FrameLayout {
   
  ...
  private FlutterView(
      @NonNull Context context,
      @Nullable AttributeSet attrs,
      @NonNull FlutterSurfaceView flutterSurfaceView) {
   
    super(context, attrs);

    this.flutterSurfaceView = flutterSurfaceView;
    this.renderSurface = flutterSurfaceView;

    init();
  }
  ...
  private void init() {
   
    ...
    addView(flutterSurfaceView);
    ...
    // FlutterView needs to be focusable so that the InputMethodManager can interact with it.
    setFocusable(true);
    setFocusableInTouchMode(true);
  }
  ...
  // 将当前FlutterView连接到给定的FLutterEngine
  // FlutterView将通过给定的FlutterEngine绘制UI,同时也将开始将后续的交互时间传递到FlutterEngine,
  // 例如触摸事件、键盘事件等。
  public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) {
   
    ...
    this.flutterEngine = flutterEngine;
    // Instruct our FlutterRenderer that we are now its designated RenderSurface.
    FlutterRenderer flutterRenderer = this.flutterEngine.getRenderer();
    ...
    renderSurface.attachToRenderer(flutterRenderer); // [5]
    ...
    // Initialize various components that know how to process Android View I/O
    // in a way that Flutter understands.
    ...
    // Push View and Context related information from Android to Flutter.
    sendUserSettingsToFlutter();
    sendLocalesToFlutter(getResources().getConfiguration());
    sendViewportMetricsToFlutter();

    flutterEngine.getPlatformViewsController().attachToView(this); // PlatformViewsController获取当前FlutterView
    ...
  }
}
  • [5] 将FlutterSurfaceViewSurface提供给指定的FlutterRender,用于将Flutter UI绘制到当前的FlutterSurfaceView
1.1.4 FlutterEngine

FlutterEngine是一个独立的Flutter运行环境,是Dart代码运行在Android应用的容器。

// ./shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java
/** Fully configurable {@code FlutterEngine} constructor. */ 
public FlutterEngine(
    @NonNull Context context,
    @NonNull FlutterLoader flutterLoader,
    @NonNull FlutterJNI flutterJNI,
    @NonNull PlatformViewsController platformViewsController,
    @Nullable String[] dartVmArgs,
    boolean automaticallyRegisterPlugins) {
   
  this.flutterJNI = flutterJNI;
  flutterLoader.startInitialization(context.getApplicationContext());
  ...
  attachToJni();
  this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets());
  this.dartExecutor.onAttachedToJNI();
  this.renderer = new FlutterRenderer(flutterJNI);
  ...
  xxxChannel = new XxxChannel(
  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董小虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值