Flutter Android启动源码分析(二)

前言

上篇文章Flutter Android启动源码分析(一)中主要对FlutterApplicaiton和FlutterActivity进行了分析,在FlutterActivity源码部分中FlutterActivityAndFragmentDelegate这个类一直被提到,这篇文章我们就主要分析一下它做了哪些事情

Flutter Android启动源码分析(一)

FlutterActivityAndFragmentDelegate

  • 作用
    • FlutterActivity和FlutterFragment之间相同的Flutter逻辑的委托
  • 为什么要用这个类
    • 假设可以在Activity中放置一个 Fragment,那么在FlutterActivity中使用一个FlutterFragment更有意义。Fragment支持库为应用程序增加了100k二进制大小,而全Flutter应用程序不需要二进制命中。因此,得出的结论是,Flutter必须基于AOSP(Android Open Source Project: Android 开源项目)Activity 提供FlutterActivity,并为应用程序添加开发人员提供独立的 FlutterFragment
    • 大概意思就是FlutterActivity和FlutterFragment是相互独立的,所以需要一个代理委托类去处理它们之间相同的逻辑
成员变量
  // Host实现类对象即FlutterActivity
  @NonNull private Host host;
  // Flutter执行环境
  @Nullable private FlutterEngine flutterEngine;
  // 闪屏View,直到FlutterView显示第一帧
  @Nullable private FlutterSplashView flutterSplashView;
  // Flutter UI
  @Nullable private FlutterView flutterView;
  // 安卓平台的插件实现
  @Nullable private PlatformPlugin platformPlugin;
  // 是否是Host实现类提供FlutterEngine
  private boolean isFlutterEngineFromHost;
构造函数
 FlutterActivityAndFragmentDelegate(@NonNull Host host) {
    this.host = host;
  }

在FlutterActivity的onCreate方法里里实例化FlutterActivityAndFragmentDelegate并传递当前FA上下文对象,

然后调用onAttach、onActivityCreated、onCreateView,下面我们对这三个方法进行逐一分析

 // FlutterActivity  删除部分源码
 @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    delegate = new FlutterActivityAndFragmentDelegate(this);
    delegate.onAttach(this);
    delegate.onActivityCreated(savedInstanceState);
    setContentView(createFlutterView());
  }
  
  @NonNull
  private View createFlutterView() {
    return delegate.onCreateView(
        null /* inflater */, null /* container */, null /* savedInstanceState */);
  }
onAttach
 void onAttach(@NonNull Context context) {
    ensureAlive();
    if (flutterEngine == null) {
    	// 1
      setupFlutterEngine();
    }
    // 2
    platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);
    // 3 
    if (host.shouldAttachEngineToActivity()) {
      flutterEngine
          .getActivityControlSurface()
          .attachToActivity(host.getActivity(), host.getLifecycle());
    }
    // 4 
    host.configureFlutterEngine(flutterEngine);
  }
  1. 实例化FlutterEngine

    	void setupFlutterEngine() {
        String cachedEngineId = host.getCachedEngineId();
        if (cachedEngineId != null) {
          flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId);
          isFlutterEngineFromHost = true;
          if (flutterEngine == null) {
            throw new IllegalStateException(
                "The requested cached FlutterEngine did not exist in the FlutterEngineCache: '"
                    + cachedEngineId
                    + "'");
          }
          return;
        }
        flutterEngine = host.provideFlutterEngine(host.getContext());
        if (flutterEngine != null) {
          isFlutterEngineFromHost = true;
          return;
        }
        flutterEngine =
            new FlutterEngine(
                host.getContext(),
                host.getFlutterShellArgs().toArray(),
                /*automaticallyRegisterPlugins=*/ false,
                /*willProvideRestorationData=*/ host.shouldRestoreAndSaveState());
        isFlutterEngineFromHost = false;
      }
    

    首先会判断是否有缓存的EngineId,如果有,去FlutterEngineCache缓存区去取到并实例化,

    如果没有,会去判断Host实现类(FlutterActivity是否有提供Engine),这个的话目前版本是返回null,

    	// FlutterActivity
    	@Nullable
      @Override
      public FlutterEngine provideFlutterEngine(@NonNull Context context) {
        // No-op. Hook for subclasses.
        return null;
      }
    

    最后就会直接去实例化一个新的Engine,然后设置isFlutterEngineFromHost 为false,说明此Engine非Host实现类提供

    我们大概看下FlutterEngine的构造函数

    public FlutterEngine(
        @NonNull Context context,
        @NonNull FlutterLoader flutterLoader,
        @NonNull FlutterJNI flutterJNI,
        @NonNull PlatformViewsController platformViewsController,
        @Nullable String[] dartVmArgs,
        boolean automaticallyRegisterPlugins,
        boolean waitForRestorationData) {
      this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets());
      this.dartExecutor.onAttachedToJNI();
    
      accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI);
      keyEventChannel = new KeyEventChannel(dartExecutor);
      lifecycleChannel = new LifecycleChannel(dartExecutor);
      localizationChannel = new LocalizationChannel(dartExecutor);
      mouseCursorChannel = new MouseCursorChannel(dartExecutor);
      navigationChannel = new NavigationChannel(dartExecutor);
      platformChannel = new PlatformChannel(dartExecutor);
      restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);
      settingsChannel = new SettingsChannel(dartExecutor);
      systemChannel = new SystemChannel(dartExecutor);
      textInputChannel = new TextInputChannel(dartExecutor);
    
      this.localizationPlugin = new LocalizationPlugin(context, localizationChannel);
    
      this.flutterJNI = flutterJNI;
      flutterLoader.startInitialization(context.getApplicationContext());
      flutterLoader.ensureInitializationComplete(context, dartVmArgs);
    
      flutterJNI.addEngineLifecycleListener(engineLifecycleListener);
      flutterJNI.setPlatformViewsController(platformViewsController);
      flutterJNI.setLocalizationPlugin(localizationPlugin);
      attachToJni();
    
      // TODO(mattcarroll): FlutterRenderer is temporally coupled to attach(). Remove that coupling if
      // possible.
      this.renderer = new FlutterRenderer(flutterJNI);
    
      this.platformViewsController = platformViewsController;
      this.platformViewsController.onAttachedToJNI();
    
      this.pluginRegistry =
          new FlutterEnginePluginRegistry(context.getApplicationContext(), this, flutterLoader);
    
      if (automaticallyRegisterPlugins) {
        registerPlugins();
      }
    }
    
    • dartExecutor实例化
    • 一些系统channel初始化
    • FlutterJNI、PlatformViewsController、FlutterRender、FlutterLoader初始化
    • 实例化FlutterEnginePluginRegistry插件注册表

    FlutterRender 就是与提供的RenderSurface协同工作,将Flutter 像素绘制到Android View层次结构中。FlutterRender管理渲染纹理,并通过JNI将一些Java调用转发到本地 Flutter代码

    FlutterLoader就是在应用程序APK中查找Flutter资源,并加载Flutter的本机库

    这两个大家可以自己去看一下,就不多提及了

  2. 实例化PlatformPlugin

     // FlutterActivity
     @Nullable
      @Override
      public PlatformPlugin providePlatformPlugin(
          @Nullable Activity activity, @NonNull FlutterEngine flutterEngine) {
        if (activity != null) {
          return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
        } else {
          return null;
        }
      }
    

    可以看到FlutterActivity重写这个方法并实例化一个新的PlatformPlugin

    这里有一个注意点:如果FlutterFragment 连接到一个新的Activity上的时候,都要重新去创建一个PlatformPlugin

    PlatformPlugin的话大家可以自己去看,就是平台提供的原生插件,如:状态栏操作、剪贴板等Plugin

  3. attachToActivity

     // FlutterActivity
     @Override
      public boolean shouldAttachEngineToActivity() {
        return true;
      }
    

    这里话默认是返回true,建立Activity和Engine的关联关系

    attachToActivity方法的作用就是通知当前连接到FlutterEngine的所有插件,将它们附加到Activity

     //  FlutterEnginePluginRegistry 插件注册表
     @Override
      public void at
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值