前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从源码看Flutter Android端的启动流程

从源码看Flutter Android端的启动流程

作者头像
用户1907613
发布2024-04-10 16:18:07
560
发布2024-04-10 16:18:07
举报
文章被收录于专栏:Android群英传Android群英传
Flutter容器

Flutter在Android中的渲染载体就是Flutter容器,通常是以Activity和Fragment的形式承载,虽然也有FlutterView,但是需要单独处理的关联方法太多,所以不太建议使用,这篇文章将分析Flutter在Android中的加载和启动流程,了解Flutter是如何在Android中加载并渲染的。

小小Android,easy easy!

FlutterActivity

FlutterActivity是最基本的Flutter容器,我们先来看看FlutterActivity的实现,类定义如下:

代码语言:javascript
复制

java
public class FlutterActivity extends Activity
    implements FlutterActivityAndFragmentDelegate.Host, LifecycleOwner {

FlutterActivityAndFragmentDelegate.Host是我们暂时唯一不熟悉的内容,先来看看它是什么。

FlutterActivityAndFragmentDelegate.Host看上去就是定义了一堆接口,这些可以理解为Flutter在运行时,需要Native所提供的抽象能力,而FlutterActivityAndFragmentDelegate,顾名思义,就是将Flutter在Activity和Fragment中的通用行为抽取出来的Delegate,从而做到功能的复用。

对于Activity来说,我们先从它的onCreate方法来看。

在FlutterActivity初始化的时候,就是通过创建FlutterActivityAndFragmentDelegate的实例来进行一些初始化操作,包括delegate.onAttach,以及后面的createFlutterView,也是通过delegate.onCreateView来创建的。

而FlutterActivity中剩下的方法,大多都是实现FlutterActivityAndFragmentDelegate.Host的接口实现,以及对生命周期的绑定。

由此可见,FlutterActivity的整体初始化流程,都被代理到了FlutterActivityAndFragmentDelegate这个天命打工人来处理了。

FlutterActivityAndFragmentDelegate

从命名就能看出这个类的重要性了,在注释中,我们可以了解到,FlutterActivityAndFragmentDelegate实现了Flutter和Activity、Fragment交互的所有逻辑。

对于这个类,我们从onAttach和onCreateView两个方法来看,这两个方法,也是在FlutterActivity的onCreate中调用的方法。

这个类的核心方法有两个,一个是setupFlutterEngine,用来创建一个FlutterEngine,另一个是host.configureFlutterEngine(flutterEngine),回调创建的Engine给外界,从而标志着Engine达到可用状态。

onCreateView方法稍微复杂一点,它会创建一个FlutterView,并将其通过setContentView设置给Activity。

首先,会判断当前的渲染模式是Surface还是Texture,从而判断是创建FlutterSurfaceView还是FlutterTextureView,但不管是哪种,最后都会封装成FlutterView,并和FlutterEngine绑定。接下来就是添加一个首帧数据渲染完成的回调,这个回调对应Host中的两个方法:onFlutterUiDisplayed和onFlutterUiNoLongerDisplayed。

FlutterSplashView这块先不用管,大部分时间用不到。

后面就会调用FlutterView的attachToFlutterEngine方法,将FlutterView和Engine进行关联。

在FlutterActivity启动的生命周期中,还有一个onStart是比较重要的时间点,在这个方法中,会开始执行FlutterView中的Dart代码,可以认为,onStart之后,才是Flutter代码执行的开始。

其中最重要的就是doInitialFlutterViewRun这个方法了。

在这个方法中,我们看见了很多熟悉的配置,例如DartEntrypoint、initialRoute等等。

FlutterFragment

FlutterFragment和FlutterActivity如出一辙,唯一不同的是,FlutterFragment多实现了一个FlutterActivityAndFragmentDelegate.DelegateFactory。

而它的实现,同样也是为了创建FlutterActivityAndFragmentDelegate。

与FlutterActivity在onCreate中创建FlutterActivityAndFragmentDelegate不同的是,FlutterFragment选择在onAttach的时候创建。

其它的流程与FlutterActivity基本一致。

FlutterFragmentActivity

从注释可以了解,FlutterFragmentActivity是对FragmentActivity的封装,帮你实现了一些要关联的生命周期API。

我们同样先来看下它的onCreate实现。

这里就很有意思了,为什么官方推荐使用FlutterFragmentActivity?原因就是这里,它对Fragment的生命周期等一系列问题,做了一些处理和防御,我们来看下这几个关键的方法。首先是retrieveExistingFlutterFragmentIfPossible。

在onCreate前,先通过tag来取一次FragmentManager中的缓存。然后再看createFragmentContainer方法。

这就是官方的实现,创建一个Fragment的容器。最后是ensureFlutterFragmentCreated方法。

在这里,会重新从缓存中再拿一次FlutterFragment,如果还是没有,那么才会通过createFlutterFragment来创建新的FlutterFragment。这里就是创建Engine的一般方法,区分了不同种类的Engine,例如NewEngine、EngineGroup等。

剩下的,就是一些生命周期函数的联动。

参考官方FlutterFragmentActivity的做法,我们可以很好的处理自己添加FlutterFragment时产生的一些生命周期问题,果然,官方的做法才是最佳实践。

FlutterActivity、FlutterFragmentActivity、FragmentActivity的关系

在使用过程中,官方推荐使用FlutterActivity来作为Flutter的容器,从而避免自己去实现一些生命周期的绑定。

那么对应FlutterFragment来说,如果载体是Activity或者是FragmentActivity,那么就需要自己来绑定一些生命周期,这些在文档中也有提到。https://flutter.cn/docs/add-to-app/android/add-flutter-fragment?tab=forward-activity-calls-kotlin-tab

所以官方提供了FlutterFragmentActivity来给你打个样,告诉你该如何写,当然你也可以直接用。

源码中的log还是很多的,通过切换不同的tag,可以找到很多有用的信息。

FlutterEngine

在FlutterActivityAndFragmentDelegate的onAttach方法中,会通过setupFlutterEngine来创建FlutterEngine,那么FlutterEngine又是个什么东西呢?

这里的代码还比较简单,无非是判断Engine类型,从而创建Engine,那么Engine到底是什么呢?我们来看下它类的定义。

从大致的结构上,我们能猜测出它的作用,实际上是对一些关键逻辑类的管理,例如FlutterJNI、FlutterRenderer和一些System channels。我们找到它的构造方法。

构造方法中,就是对这些逻辑管理类的一一初始化,还有插件的初始化,一个是FlutterEngineConnectionRegistry,另一个是GeneratedPluginRegister.registerGeneratedPlugins,这个东西,就是我们熟悉的内容了。

这就是我们在Flutter中注册的这些插件,就是在此时此地初始化的。

FlutterLoader

在初始化过程中,我们还看见一个陌生的类——FlutterLoader。

这个类是一个用于加载相关so资源的辅助类,我们主要关注它的startInitialization方法,而它里面最重要的就是对VsyncWaiter的初始化。

这个类就是刷新同步的处理类。

VsyncWaiter

现代屏幕的刷新,是通过显示器的VSync信号来进行同步的,VsyncWaiter这个类,就是Flutter中这个信号的接收者,当我们调用它的init方法时,就是注册一个我们熟悉的Choreographer.FrameCallback,这就是Android中的VSync回调。

在每次VSync信号的回调中,通过flutterJNI的Native方法,将同步信号传递给Flutter。

FlutterEngineGroup

FlutterEngineGroup维护了一个多引擎的管理实例。

我们来看下构造方法。

从上面的代码中我们可以发现,FlutterEngineGroup创建Engine的逻辑,当Engine不存在时,和普通FlutterEngine的创建是一样的,当Engine存在时,直接通过spawn方法来创建新的Engine实例。

而这里又通过Native的spawn方法来创建新的JNI实例。

FlutterEngineGroup正是通过这种方式,实现了低成本、高效率的Engine创建。

FlutterView

在FlutterActivityAndFragmentDelegate的onCreateView方法中,会创建FlutterView,这也是Android中用于承载Flutter内容的容器,我们来看下它的类申明。

看来,FlutterView实际上是一个FrameLayout,这是因为它内部会放上不同的Child,例如FlutterSurfaceView、FlutterTextureView。它们的区别在文档中也有说明。

大部分时间,我们使用Surface模式即可,只有当需要使用透明背景且有一些和NativeView的层级影响时,才需要使用Texture模式。同样的,我们先来看下FlutterSurfaceView的类定义。

它其实就是一个SurfaceView,同样会在SurfaceHolder.Callback中创建渲染逻辑。

实际的渲染逻辑在这里。

最后压力给到了FlutterRenderer,看来渲染的实际打工人就是它了。

FlutterTextureView和它类似,就不单独看了。

不管是哪一种,它们都实现了RenderSurface接口,用于FlutterRenderer来调用其抽象方法。

最后在FlutterView的init方法中,我们看到了具体的FlutterView是如何添加到容器中的。

FlutterImageView用的比较少,这里也不作展开。

FlutterRenderer

国际惯例,先看FlutterRenderer的申明。

由此可见,FlutterRenderer的作用,就是连接了两个重要的内容:FlutterJNI和Surface。在startRenderingToSurface方法中,就是它们的关联方法。FlutterRenderer借助FlutterJNI,将Flutter的纹理渲染到Surface中,从而实现Flutter的画面渲染。

最后再整理下流程,最开始在FlutterActivityAndFragmentDelegate的onCreateView中,我们创建FlutterView,并调用FlutterView实例的attachToFlutterEngine方法将Engine的FlutterRenderer和RenderSurface的具体实现(FlutterSurfaceView或者是FlutterTextureView)进行绑定,从而将这一切捆绑起来。

事件传递

既然FlutterView是一个标准的AndroidView,那么它的事件是如何传递给Flutter的呢?首先,我们来看Android的一些系统回调,例如下面这些。

剩下的就不截图了,可以参考源码中的Process View configuration that Flutter cares about这部分注释。这些代码基本类似,都是在这些Android的原生回调中,将事件传递到Flutter中,例如onSizeChanged回调中的sendViewportMetricsToFlutter方法。

还有点击事件的处理,我们来看onTouchEvent和dispatchKeyEvent方法。

最后的打工人,又来到了androidTouchProcessor,它是在attachToFlutterEngine的时候初始化的,AndroidTouchProcessor就是将触摸事件转发到Flutter的核心类。

上帝视角

来个整体流程图。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 群英传 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • FlutterActivity
    • FlutterActivityAndFragmentDelegate
    • FlutterFragment
    • FlutterFragmentActivity
    • FlutterActivity、FlutterFragmentActivity、FragmentActivity的关系
    • FlutterEngine
      • FlutterLoader
        • VsyncWaiter
          • FlutterEngineGroup
          • FlutterView
            • FlutterRenderer
              • 事件传递
              • 上帝视角
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档