关于flutter:Flutter-Android-端-ActivityFragment-流程源码分析

52次阅读

共计 24023 个字符,预计需要花费 61 分钟才能阅读完成。

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

这里不做过多演示。

正文完
 0