Flutter 系列文章连载~

  • 《Flutter Android 工程构造及应用层编译源码深入分析》
  • 《Flutter 命令实质之 Flutter tools 机制源码深入分析》
  • 《Flutter 的 runApp 与三棵树诞生流程源码剖析》
  • 《Flutter Android 端 Activity/Fragment 流程源码剖析》
  • 《Flutter Android 端 FlutterInjector 及依赖流程源码剖析》
  • 《Flutter Android 端 FlutterEngine Java 相干流程源码剖析》
  • 《Flutter Android 端 FlutterView 相干流程源码剖析》
  • 《Flutter 绘制动机 VSYNC 流程源码全方位剖析》
  • 《Flutter 安卓 Platform 与 Dart 端音讯通信形式 Channel 源码解析》

背景

后面文章咱们剖析了 flutter 在 android 端编译命令相干流程,咱们接下来须要先剖析一下 Flutter Android 端 framework 平台实现代码(非 native engine 引擎局部),上面以一个纯 Flutter App 为例开展剖析。

工程构造及 API 变更

对于一个纯 flutter app 来说,当咱们在 yaml 依赖中增加两个 flutter plugin 依赖,而后铜过 Android Studio 导入安卓工程后能够看到如下构造:

gradle sync 后对应的安卓依赖如下:

能够看到,下面依赖就是咱们《Flutter Android 工程构造及应用层编译源码深入分析》一文中剖析 Flutter Android App 编译流程中提到过的动静追加依赖。

对于 Android 平台来说,Flutter 依赖其实蛮简略的,咱们以启用 androidx 为例展现 release 模式下的依赖关系,如下:

releaseRuntimeClasspath - Resolved configuration for runtime for variant: release+--- io.flutter:flutter_embedding_release:1.0.0-241c87ad800beeab545ab867354d4683d5bfb6ce|    +--- androidx.lifecycle:lifecycle-common:2.2.0|    |    \--- androidx.annotation:annotation:1.1.0|    +--- androidx.lifecycle:lifecycle-common-java8:2.2.0|    |    +--- androidx.lifecycle:lifecycle-common:2.2.0 (*)|    |    \--- androidx.annotation:annotation:1.1.0|    +--- androidx.lifecycle:lifecycle-runtime:2.2.0|    |    +--- androidx.lifecycle:lifecycle-common:2.2.0 (*)|    |    +--- androidx.arch.core:core-common:2.1.0|    |    |    \--- androidx.annotation:annotation:1.1.0|    |    \--- androidx.annotation:annotation:1.1.0|    +--- androidx.fragment:fragment:1.1.0|    |    +--- androidx.annotation:annotation:1.1.0|    |    +--- androidx.core:core:1.1.0|    |    |    +--- androidx.annotation:annotation:1.1.0|    |    |    +--- androidx.lifecycle:lifecycle-runtime:2.0.0 -> 2.2.0 (*)|    |    |    +--- androidx.versionedparcelable:versionedparcelable:1.1.0|    |    |    |    \--- androidx.collection:collection:1.0.0 -> 1.1.0|    |    |    |         \--- androidx.annotation:annotation:1.1.0|    |    |    \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*)|    |    +--- androidx.collection:collection:1.1.0 (*)|    |    +--- androidx.viewpager:viewpager:1.0.0|    |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.1.0|    |    |    +--- androidx.core:core:1.0.0 -> 1.1.0 (*)|    |    |    \--- androidx.customview:customview:1.0.0|    |    |         +--- androidx.annotation:annotation:1.0.0 -> 1.1.0|    |    |         \--- androidx.core:core:1.0.0 -> 1.1.0 (*)|    |    +--- androidx.loader:loader:1.0.0|    |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.1.0|    |    |    +--- androidx.core:core:1.0.0 -> 1.1.0 (*)|    |    |    +--- androidx.lifecycle:lifecycle-livedata:2.0.0|    |    |    |    +--- androidx.arch.core:core-runtime:2.0.0|    |    |    |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.1.0|    |    |    |    |    \--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)|    |    |    |    +--- androidx.lifecycle:lifecycle-livedata-core:2.0.0|    |    |    |    |    +--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.2.0 (*)|    |    |    |    |    +--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)|    |    |    |    |    \--- androidx.arch.core:core-runtime:2.0.0 (*)|    |    |    |    \--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)|    |    |    \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.1.0|    |    |         \--- androidx.annotation:annotation:1.1.0|    |    +--- androidx.activity:activity:1.0.0|    |    |    +--- androidx.annotation:annotation:1.1.0|    |    |    +--- androidx.core:core:1.1.0 (*)|    |    |    +--- androidx.lifecycle:lifecycle-runtime:2.1.0 -> 2.2.0 (*)|    |    |    +--- androidx.lifecycle:lifecycle-viewmodel:2.1.0 (*)|    |    |    \--- androidx.savedstate:savedstate:1.0.0|    |    |         +--- androidx.annotation:annotation:1.1.0|    |    |         +--- androidx.arch.core:core-common:2.0.1 -> 2.1.0 (*)|    |    |         \--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.2.0 (*)|    |    \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.1.0 (*)|    \--- androidx.annotation:annotation:1.1.0+--- io.flutter:armeabi_v7a_release:1.0.0-241c87ad800beeab545ab867354d4683d5bfb6ce+--- io.flutter:arm64_v8a_release:1.0.0-241c87ad800beeab545ab867354d4683d5bfb6ce\--- io.flutter:x86_64_release:1.0.0-241c87ad800beeab545ab867354d4683d5bfb6ce

能够看到依赖次要都是 androidx,还是蛮香的。

源码剖析

Flutter Android 端源码次要依赖于 gradle maven 下载,也就是上图中的io.flutter:flutter_embedding_XXX代码,另一个 ABI 依赖是libflutter.so引擎依赖。

本文以 Flutter 2.2.3 版本为例剖析,因为新旧版本的 Android 入口存在差别,譬如新版本不再默认应用FlutterApplication配合io.flutter.app.FlutterActivity模式,而是间接应用io.flutter.embedding.android.FlutterActivty,所以咱们的入口要从新的看起(留神新旧同类名不同包名的区别)。相干新旧版本迁徙变更能够参考官网阐明的Upgrading-pre-1.12-Android-projects。

FlutterActivity 相干剖析

Android App 中默认 Flutter UI 界面出现在平台层的实现都继承自io.flutter.embedding.android.FlutterActivity,主题默认也是一个全屏无 ActionBar 模式,源码如下:

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

根据这个继承关系能够看到,FlutterActivity 间接继承自 Activity,而不是兼容包的 AppCompatActivity,这对于有历史包袱的 App 来说是一件坏事,也秉承了一个优质 SDK 去依赖的优质特点。同时其实现了两个接口,LifecycleOwner 为规范 AAC 框架成员,咱们不再解释;重点看下FlutterActivityAndFragmentDelegate.Host,源码如下:

class FlutterActivityAndFragmentDelegate implements ExclusiveAppComponent<Activity> {  ......  //这里的一堆extends接口不多解释,正文都很明确  interface Host      extends SplashScreenProvider,          FlutterEngineProvider,          FlutterEngineConfigurator,          PlatformPlugin.PlatformPluginDelegate {    //1、获取宿主Activity或Fragment的context。    //对应下面FlutterActivity实现此接口就是返回他本人的context,也就是this。    @NonNull    Context getContext();    //2、是否能够通过deeplink调起initial route路由。    //次要是在AndroidManifest.xml中Activity配置flutter_deeplinking_enabled meta值。    //参见官网文档 https://flutter.dev/docs/development/ui/navigation/deep-linking    @Nullable    boolean shouldHandleDeeplinking();    //3、获取宿主Activity或Fragment的attached Activity。    //对应下面FlutterActivity实现此接口就是返回他本人,也就是this。    @Nullable    Activity getActivity();    //4、获取宿主Activity或Fragment的Lifecycle。    @NonNull    Lifecycle getLifecycle();    //5、获取宿主启动Flutter携带的参数,通过intent解析,譬如enable-dart-profiling等。    @NonNull    FlutterShellArgs getFlutterShellArgs();    //6、获取动态缓存的EngineId,如果没有就返回空,通过intent的cached_engine_id参数传递。    @Nullable    String getCachedEngineId();    //7、当FlutterActivity destory后是否销毁引擎实例,默认要销毁。    //当FlutterEngine属于Activity本人则须要销毁返回true,当FlutterEngine属于动态缓存的,则不必销毁,这里应该返回false。    boolean shouldDestroyEngineWithHost();    //8、当FlutterEngine曾经attach到另一个Activity时这个Activity就须要与FlutterEngine断开。    void detachFromFlutterEngine();    //9、获取dart主入口,默认时main。    //能够在AndroidManifest.xml中给Activity设置io.flutter.Entrypoint的meta自定义。    @NonNull    String getDartEntrypointFunctionName();    //10、返回app bundle dart代码存在的门路。    @NonNull    String getAppBundlePath();    //11、获取初始路由地址。    //默认先从intent中解析route的值,没有就去meta-data解析io.flutter.InitialRoute的值,没有就返回null。    @Nullable    String getInitialRoute();    //12、获取渲染模式,用在FlutterView出现FlutterEngine引擎渲染成果。    @NonNull    RenderMode getRenderMode();    //13、获取Transparency模式,用在FlutterView出现FlutterEngine引擎渲染成果。    @NonNull    TransparencyMode getTransparencyMode();    //14、提供一个Flutter开屏图片,默认有配置。    //通过meta-data配置io.flutter.embedding.android.SplashScreenDrawable可失效。    @Nullable    SplashScreen provideSplashScreen();    //15、返回一个用来渲染FlutterView的FlutterEngine引擎。    //如果返回null则框架会主动新建一个FlutterEngine引擎实例,默认就是主动新建,咱们能够重写复用等。    @Nullable    FlutterEngine provideFlutterEngine(@NonNull Context context);    //16、创立和配置platform plugin。    @Nullable    PlatformPlugin providePlatformPlugin(        @Nullable Activity activity, @NonNull FlutterEngine flutterEngine);    void configureFlutterEngine(@NonNull FlutterEngine flutterEngine);    void cleanUpFlutterEngine(@NonNull FlutterEngine flutterEngine);    boolean shouldAttachEngineToActivity();    void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView);    void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView);    void onFlutterUiDisplayed();    void onFlutterUiNoLongerDisplayed();    boolean shouldRestoreAndSaveState();  }}

能够看到FlutterActivityAndFragmentDelegate.Host是 Flutter Android 平台层实现与规范 Activity/Fragment 之间的一个接口约定层,FlutterActivity 实现了这个接口的一系列办法,这些接口的含意下面也列举了,所以咱们上面重心回到规范 Android Activity 生命周期线,如下:

public class FlutterActivity extends Activity    implements FlutterActivityAndFragmentDelegate.Host, LifecycleOwner {  ......  //步骤1、重点!关联Activity、Fragment与Flutter的接口桥梁委托实现  protected FlutterActivityAndFragmentDelegate delegate;  ......  @Override  protected void onCreate(@Nullable Bundle savedInstanceState) {      //步骤2、将清单文件中标准配置的主题切换回一般主题。很奇妙的让launch app和initialized后activity主题发生变化。      //一般主题通过io.flutter.embedding.android.NormalTheme的meta-data配置。      //清单标准配置的是一个图标、启动后执行到这里被换成规范纯背景色,两个主题不要对窗体size进行差别配置,不然会抖动。    switchLaunchThemeForNormalTheme();    super.onCreate(savedInstanceState);    //步骤3、创立一个委托代理类实例,而后调用他的一系列办法。    delegate = new FlutterActivityAndFragmentDelegate(this);    delegate.onAttach(this);    delegate.onRestoreInstanceState(savedInstanceState);    //步骤4、规范AAC操作,不解释。    lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);    //步骤5、从Activity的Intent中解析background_mode字段看是transparent还是opaque。    //通明则通过getWindow().setBackgroundDrawable设置为通明,否则放弃NormalTheme的暗黑适配纯色背景。    configureWindowForTransparency();    //步骤6、创立一个View让Activity显示,这就是Flutter的View容器。    setContentView(createFlutterView());    //步骤7、官网对全屏状态栏的兼容配置。。。    configureStatusBarForFullscreenFlutterExperience();  }  ......  //步骤8、创立并返回一个View用来给Activity显示。  @NonNull  private View createFlutterView() {    return delegate.onCreateView(        null /* inflater */, null /* container */, null /* savedInstanceState */);  }  //步骤9、官网对全屏状态栏的兼容配置。  //这些flag不必解释了吧,规范安卓操作。  //记住这个坑即可,咱们如果想批改FlutterActivity的这玩意就在他之后笼罩即可。  private void configureStatusBarForFullscreenFlutterExperience() {    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {      Window window = getWindow();      window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);      window.setStatusBarColor(0x40000000);      window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);    }  }    //步骤10、生命周期回调解决,AAC调用、delegate对应办法触发等  @Override  protected void onStart() {    super.onStart();    lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START);    //判断delegate是否不为null    if (stillAttachedForEvent("onStart")) {      delegate.onStart();    }  }      //步骤11、同步骤10的一堆回调相似触发,省略实现。。。  @Override  protected void onResume() {......}  @Override  public void onPostResume() {......}  @Override  protected void onPause() {......}  @Override  protected void onStop() {......}  @Override  protected void onSaveInstanceState(Bundle outState) {......}  @Override  protected void onDestroy() {......}  @Override  protected void onActivityResult(int requestCode, int resultCode, Intent data) {......}  @Override  protected void onNewIntent(@NonNull Intent intent) {......}  @Override  public void onBackPressed() {......}  @Override  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {......}  @Override  public void onUserLeaveHint() {......}  @Override  public void onTrimMemory(int level) {......}  ......  //步骤12、一堆后面介绍的FlutterActivityAndFragmentDelegate.Host接口实现办法。  ......}

FlutterActivityAndFragmentDelegate 相干剖析

上一大节咱们看到 FlutterActivity 中的外围就是与 FlutterActivityAndFragmentDelegate 实例进行交互,那咱们就持续看看这个实例对应的源码,重点先放到 FlutterActivity 中调用的实例化、onAttach、onRestoreInstanceState 上。如下:

class FlutterActivityAndFragmentDelegate implements ExclusiveAppComponent<Activity> {  private static final String TAG = "FlutterActivityAndFragmentDelegate";  private static final String FRAMEWORK_RESTORATION_BUNDLE_KEY = "framework";  private static final String PLUGINS_RESTORATION_BUNDLE_KEY = "plugins";  //步骤1、host实例就是FlutterActivity或FlutterFragment  @NonNull private Host host;  @Nullable private FlutterEngine flutterEngine;  @Nullable private FlutterSplashView flutterSplashView;  @Nullable private FlutterView flutterView;  @Nullable private PlatformPlugin platformPlugin;  private boolean isFlutterEngineFromHost;      //步骤2、后面大节FlutterActivity的onCreate中实例化,host为FlutterActivity本人的this。  FlutterActivityAndFragmentDelegate(@NonNull Host host) {    this.host = host;  }    //步骤3、后面大节FlutterActivity的onCreate中调用  void onAttach(@NonNull Context context) {    //确保host不为空,否则抛出异样。    ensureAlive();    //步骤4、flutterEngine为空就创立。    if (flutterEngine == null) {      setupFlutterEngine();    }    //步骤5、后面大节FlutterActivity中接口实现,默认为true。    if (host.shouldAttachEngineToActivity()) {      //步骤6、flutterEngine与FlutterActivity进行attach关联。      Log.v(TAG, "Attaching FlutterEngine to the Activity that owns this delegate.");      flutterEngine.getActivityControlSurface().attachToActivity(this, host.getLifecycle());    }    //步骤7、通过host获取PlatformPlugin实例。    platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);    //步骤8、给host配置flutterEngine。    host.configureFlutterEngine(flutterEngine);  }  //步骤9、后面大节FlutterActivity的onCreate中调用  void onRestoreInstanceState(@Nullable Bundle bundle) {    Log.v(        TAG,        "onRestoreInstanceState. Giving framework and plugins an opportunity to restore state.");    ensureAlive();    //步骤10、这两个变量都是在Activity的onSaveInstanceState办法进行set操作赋值的。    Bundle pluginState = null;    byte[] frameworkState = null;    if (bundle != null) {      //阐明来自异样终止复原Activity      pluginState = bundle.getBundle(PLUGINS_RESTORATION_BUNDLE_KEY);      frameworkState = bundle.getByteArray(FRAMEWORK_RESTORATION_BUNDLE_KEY);    }    //步骤11、寄存时也是这个规定,优先判断intent中的enable_state_restoration配置。    //不存在就看getCachedEngineId是不是不为null,是就不会要复原,即此条件false,反之复原。    if (host.shouldRestoreAndSaveState()) {      flutterEngine.getRestorationChannel().setRestorationData(frameworkState);    }    //步骤12、FlutterActivity默认实现是true。    if (host.shouldAttachEngineToActivity()) {      flutterEngine.getActivityControlSurface().onRestoreInstanceState(pluginState);    }  }  ......}

看完下面这段,接下来咱们持续把眼光挪到 FlutterActivityAndFragmentDelegate 的 onCreateView 办法上,这个办法的返回值在后面 FlutterActivity 的 onCreate 中被 setContent 设置为 Activity 的 View。如下:

class FlutterActivityAndFragmentDelegate implements ExclusiveAppComponent<Activity> {  ......  //步骤13、FlutterActivity中调用时参数均为null,返回一个androd view实例。  @NonNull  View onCreateView(      LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {    Log.v(TAG, "Creating FlutterView.");    //确保host属性不为null。    ensureAlive();    //步骤14、根据后面FlutterActivity的intent参数background_mode决定模式,默认surface模式。    //FlutterActivity默认背景是opaque、能够设置为transparent。    //当FlutterActivity的window背景不通明则RenderMode为surface模式、反之texture模式。    if (host.getRenderMode() == RenderMode.surface) {      //步骤15、创立一个FlutterSurfaceView。      //而后通过host接口调用FlutterActivity的onFlutterSurfaceViewCreated办法,默认空实现。      //getTransparencyMode模式和FlutterActivity的window背景模式齐全一样逻辑。      FlutterSurfaceView flutterSurfaceView =          new FlutterSurfaceView(              host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent);      host.onFlutterSurfaceViewCreated(flutterSurfaceView);      //步骤15、创立一个FlutterView蕴含FlutterSurfaceView。      flutterView = new FlutterView(host.getActivity(), flutterSurfaceView);    } else {      //步骤16、创立一个FlutterTextureView。      //而后通过host接口调用FlutterActivity的onFlutterSurfaceViewCreated办法,默认空实现。      FlutterTextureView flutterTextureView = new FlutterTextureView(host.getActivity());      host.onFlutterTextureViewCreated(flutterTextureView);      //步骤17、创立一个FlutterView蕴含FlutterTextureView。      flutterView = new FlutterView(host.getActivity(), flutterTextureView);    }    //步骤18、增加监听,当flutter渲染首帧时回调。    flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener);    //步骤19、创立一个FlutterSplashView开屏view    flutterSplashView = new FlutterSplashView(host.getContext());    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {      flutterSplashView.setId(View.generateViewId());    } else {      //这里不得不吐槽官网,不过的确没好的方法,间接写死了一个随机id,有可能抵触,且一个view树只能有一个FlutterSplashView了。      flutterSplashView.setId(486947586);    }    //步骤20、显示开屏图标,即io.flutter.embedding.android.SplashScreenDrawable配置的drawable图。    flutterSplashView.displayFlutterViewWithSplash(flutterView, host.provideSplashScreen());    //步骤21、FlutterView与flutterEngine关联attach。    Log.v(TAG, "Attaching FlutterEngine to FlutterView.");    flutterView.attachToFlutterEngine(flutterEngine);    //返回被开屏view包裹的FlutterView。    return flutterSplashView;  }  //步骤22、一组回调监听定义,回调中实质是触发调用对应FlutterActivity或FlutterFragment的FlutterActivityAndFragmentDelegate.Host实现办法。  @NonNull  private final FlutterUiDisplayListener flutterUiDisplayListener =      new FlutterUiDisplayListener() {        @Override        public void onFlutterUiDisplayed() {          //实质在FlutterActivity中调用Activity 5.0以上的reportFullyDrawn()安卓官网办法。          host.onFlutterUiDisplayed();        }        @Override        public void onFlutterUiNoLongerDisplayed() {          //实质在FlutterActivity中调用,默认空实现。          host.onFlutterUiNoLongerDisplayed();        }      };  ......}

接着持续看 FlutterActivity 生命周期及事件相干办法对 FlutterActivityAndFragmentDelegate 相干办法的调用,如下:

class FlutterActivityAndFragmentDelegate implements ExclusiveAppComponent<Activity> {  ......  void onStart() {    ......    doInitialFlutterViewRun();  }  //步骤23、开始在FlutterView中执行dart程序。  private void doInitialFlutterViewRun() {    ......    //步骤24、判断是否dart曾经运行中。    //这个状况只会产生在config change后咱们没有保留Fragment实例的场景,尽量不要这样。    if (flutterEngine.getDartExecutor().isExecutingDart()) {      return;    }    //步骤25、各种优先级获取初始跳转dart的路由地址。    String initialRoute = host.getInitialRoute();    if (initialRoute == null) {      initialRoute = maybeGetInitialRouteFromIntent(host.getActivity().getIntent());      if (initialRoute == null) {        initialRoute = DEFAULT_INITIAL_ROUTE; //值为 /      }    }    //过滤这个tag能够调试flutter初始路由跳转信息。    Log.v(        TAG,        "Executing Dart entrypoint: "            + host.getDartEntrypointFunctionName()            + ", and sending initial route: "            + initialRoute);    //步骤26、通过引擎的NavigationChannel设置初始路由信息。    flutterEngine.getNavigationChannel().setInitialRoute(initialRoute);    //步骤27、依照优先级获取appBundlePath,默认从host获取,无则从FlutterLoader获取。    String appBundlePathOverride = host.getAppBundlePath();    if (appBundlePathOverride == null || appBundlePathOverride.isEmpty()) {      appBundlePathOverride = FlutterInjector.instance().flutterLoader().findAppBundlePath();    }    //步骤28、配置dart的entrypoint并且执行,默认入口函数名为main,可通过meta-data的io.flutter.Entrypoint批改。    DartExecutor.DartEntrypoint entrypoint =        new DartExecutor.DartEntrypoint(            appBundlePathOverride, host.getDartEntrypointFunctionName());    flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint);  }  ......  //步骤29、FlutterActivity的onResume调用它。  void onResume() {    ......    //调用引擎的LifecycleChannel触发办法。    flutterEngine.getLifecycleChannel().appIsResumed();  }  //步骤30、雷同onResume不做阐明,都是调用flutterEngine.getLifecycleChannel()的对应办法。  void onPause() {......}  void onStop() {......}  void onUserLeaveHint() {......}  ......  void onPostResume() {    ......    if (flutterEngine != null) {      if (platformPlugin != null) {        //步骤31、即FlutterActivity中providePlatformPlugin办法返回的PlatformPlugin实例。        platformPlugin.updateSystemUiOverlays();      }    } else {      Log.w(TAG, "onPostResume() invoked before FlutterFragment was attached to an Activity.");    }  }  ......  //步骤32、返回按钮触发,通过NavigationChannel通道退栈route。  void onBackPressed() {    ensureAlive();    if (flutterEngine != null) {      Log.v(TAG, "Forwarding onBackPressed() to FlutterEngine.");      flutterEngine.getNavigationChannel().popRoute();    } else {      Log.w(TAG, "Invoked onBackPressed() before FlutterFragment was attached to an Activity.");    }  }  //步骤33、动静权限申请返回解决,转发到感兴趣的Flutter Plugin去。  void onRequestPermissionsResult(      int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {    ensureAlive();    if (flutterEngine != null) {      ......      flutterEngine          .getActivityControlSurface()          .onRequestPermissionsResult(requestCode, permissions, grantResults);    } else {      Log.w(          TAG,          "onRequestPermissionResult() invoked before FlutterFragment was attached to an Activity.");    }  }  //步骤34、activity result返回解决,转发到感兴趣的Flutter Plugin去。  void onActivityResult(int requestCode, int resultCode, Intent data) {    ensureAlive();    if (flutterEngine != null) {      ......      flutterEngine.getActivityControlSurface().onActivityResult(requestCode, resultCode, data);    } else {      Log.w(TAG, "onActivityResult() invoked before FlutterFragment was attached to an Activity.");    }  }  //步骤35、通过SystemChannel发送低内存音讯。  void onLowMemory() {    Log.v(TAG, "Forwarding onLowMemory() to FlutterEngine.");    ensureAlive();    flutterEngine.getDartExecutor().notifyLowMemoryWarning();    flutterEngine.getSystemChannel().sendMemoryPressureWarning();  }  ......}

通过这一大节的代码段剖析,咱们能够看进去 Flutter 在平台 SDK 层包装都是 FlutterActivityAndFragmentDelegate 来负责的,FlutterActivityAndFragmentDelegate 和外围是 FlutterView 和 FlutterEngine 的创立关联与治理调度。

FlutterFragment 相干剖析

剖析完下面 FlutterActivity 相干流程,咱们接着看看 FlutterFragment,继承自androidx.fragment.app.Fragment,话中有话就是说 Activity 也得最好是用配套的 FlutterFragmentActivity。对于 FlutterFragmentActivity 咱们会在下一个大节剖析,这里重点关注 FlutterFragment。

其实官网正文也明确阐明了,他们不是特地优先举荐应用 FlutterFragment,倡议尽可能优选 FlutterActivity。因为应用 FlutterFragment 如果配合的 Activity 不是 FlutterFragmentActivity,须要咱们本人去关联一些 Activity 与 FlutterFragment 的办法,这些办法在 FlutterFragment 的源码中都以@ActivityCallThrough进行了正文申明,让应用变的没那么不便,譬如:

  • onPostResume()
  • onBackPressed()
  • onRequestPermissionsResult(int, String[], int[])} ()
  • onNewIntent(Intent)} ()
  • onUserLeaveHint()

如上 FlutterFragment 中的办法都须要被动与 Acitivty 关联调用(FlutterFragmentActivity 已实现)。上面是 FlutterFragment 的次要源码:

//步骤36、FlutterFragment也实现了后面剖析的FlutterActivityAndFragmentDelegate.Host接口,含意不解释。public class FlutterFragment extends Fragment    implements FlutterActivityAndFragmentDelegate.Host, ComponentCallbacks2 {  ......  @Override  public void onAttach(@NonNull Context context) {    super.onAttach(context);    //步骤37、与FlutterActivity的区别在于FlutterFragment在他本人的onAttach中实例化FlutterActivityAndFragmentDelegate并调用onAttach办法。    delegate = new FlutterActivityAndFragmentDelegate(this);    delegate.onAttach(context);  }  @Override  public void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    //步骤38、与FlutterActivity相似,不做过多剖析阐明。    delegate.onRestoreInstanceState(savedInstanceState);  }  @Nullable  @Override  public View onCreateView(      LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {    //步骤39、与FlutterActivity相似,只不过是在FlutterFragment对应生命周期回调。    return delegate.onCreateView(inflater, container, savedInstanceState);  }  ......  //步骤39、与FlutterActivity相似,只是这个办法不是Fragment本人框架回调,须要依赖在Activity中调用。  //譬如FlutterFragmentActivity中对应同名办法的实现。  //留神这里的@ActivityCallThrough注解就是这个含意。  @ActivityCallThrough  public void onPostResume() {    delegate.onPostResume();  }  ......}

能够看到,FlutterFragment 和 FlutterActivity 根本没啥区别,外围都是实现了FlutterActivityAndFragmentDelegate.Host接口,在本人生命周期内先实例化一个 FlutterActivityAndFragmentDelegate,接着调用其一系列办法进行交互,后面 FlutterActivity 曾经解释过了,这里不多解释。

FlutterFragmentActivity 相干剖析

通过下面 FlutterFragment 源码咱们能够看到,FlutterFragmentActivity 能够说是 FlutterFragment 的一个承载 Activity,这个 Activity 继承自androidx.fragment.app.FragmentActivity,所以应用 FlutterFragment 及 FlutterFragmentActivity 对你利用的基类 Activity 还是有一点限度的,没有后面介绍的 FlutterActivity 香。

因为 FlutterFragmentActivity 继承自androidx.fragment.app.FragmentActivity,所以相比 FlutterActivity 来说,AAC 架构那套就不必本人显式关联了,因为androidx.fragment.app.FragmentActivity外部已做好关联解决。

//步骤40、这里implements的一堆其实FlutterActivityAndFragmentDelegate.Host都有implements,算是Host的子集吧。//实质和FlutterActivityAndFragmentDelegate.Host对于实现方干的一样的事。public class FlutterFragmentActivity extends FragmentActivity    implements SplashScreenProvider, FlutterEngineProvider, FlutterEngineConfigurator {  @Override  protected void onCreate(@Nullable Bundle savedInstanceState) {    //步骤41、这里和FlutterActivity齐全一样,只是不必实例化一个FlutterActivityAndFragmentDelegate,因为其外部的FlutterFragment会做这些事。    switchLaunchThemeForNormalTheme();    super.onCreate(savedInstanceState);    configureWindowForTransparency();    //步骤42、这里区别是调用createFragmentContainer生成了一个View设置给Activity的content。    setContentView(createFragmentContainer());    //步骤43、这里和FlutterActivity齐全一样。    configureStatusBarForFullscreenFlutterExperience();    //步骤44、与FlutterActivity不一样,这里测验的是FlutterFragment是否增加OK。    ensureFlutterFragmentCreated();  }  //步骤45、下面步骤42设置的View,用来搁置FlutterFragment的容器View,实质是一个FrameLayout且MATCH_PARENT。  @NonNull  private View createFragmentContainer() {    FrameLayout container = provideRootLayout(this);    container.setId(FRAGMENT_CONTAINER_ID);    container.setLayoutParams(        new ViewGroup.LayoutParams(            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));    return container;  }  protected FrameLayout provideRootLayout(Context context) {    return new FrameLayout(context);  }  //步骤46、确保给Activity上attach一个FlutterFragment,不存在就创立一个通过FragmentManager增加。  private void ensureFlutterFragmentCreated() {    FragmentManager fragmentManager = getSupportFragmentManager();    flutterFragment = (FlutterFragment) fragmentManager.findFragmentByTag(TAG_FLUTTER_FRAGMENT);    if (flutterFragment == null) {      flutterFragment = createFlutterFragment();      fragmentManager          .beginTransaction()          .add(FRAGMENT_CONTAINER_ID, flutterFragment, TAG_FLUTTER_FRAGMENT)          .commit();    }  }  //步骤47、创立一个FlutterFragment。  //如果咱们自定义FlutterFragmentActivity子类,能够重写这个办法实现本人的自定义FlutterFragment。  @NonNull  protected FlutterFragment createFlutterFragment() {    final BackgroundMode backgroundMode = getBackgroundMode();    final RenderMode renderMode = getRenderMode();    final TransparencyMode transparencyMode =        backgroundMode == BackgroundMode.opaque            ? TransparencyMode.opaque            : TransparencyMode.transparent;    //步骤48、根据是否Engine缓存决定怎么创立FlutterFragment。    if (getCachedEngineId() != null) {      ......      return FlutterFragment.withCachedEngine(getCachedEngineId())          .renderMode(renderMode)          .transparencyMode(transparencyMode)          .handleDeeplinking(shouldHandleDeeplinking())          .shouldAttachEngineToActivity(shouldAttachEngineToActivity())          .destroyEngineWithFragment(shouldDestroyEngineWithHost())          .build();    } else {      ......      return FlutterFragment.withNewEngine()          .dartEntrypoint(getDartEntrypointFunctionName())          .initialRoute(getInitialRoute())          .appBundlePath(getAppBundlePath())          .flutterShellArgs(FlutterShellArgs.fromIntent(getIntent()))          .handleDeeplinking(shouldHandleDeeplinking())          .renderMode(renderMode)          .transparencyMode(transparencyMode)          .shouldAttachEngineToActivity(shouldAttachEngineToActivity())          .build();    }  }  ......  //步骤49、调用flutterFragment对应生命周期回调。  //能够看到,应用FlutterFragmentActivity配合FlutterFragment的益处就是这些FlutterFragment的@ActivityCallThrough都帮你调用好了。  @Override  public void onPostResume() {    super.onPostResume();    flutterFragment.onPostResume();  }  ......}

总结

到此咱们其实就晓得 FlutterActivity 和 FlutterFragment 的大抵实现,置信你通过下面剖析对 Flutter App 在安卓端的承载有肯定意识,通常一个 engine 的整个 Flutter Dart 无论页面栈多少级,终归在安卓端都是一个 Activity 或者 Fragment 承载,抑或 View,端侧仅仅算是一个容器而已。

这也就是为什么咱们在 Android 平台上查看一个规范 Flutter App 的 Activity 堆栈默认只有继承自 FlutterActivity 的一个 Activity,其外部 View 层级如下的起因:

对于本文更多样例能够参见官网文档:

  • add-flutter-screen
  • add-flutter-fragment
  • add-flutter-view

这里不做过多演示。