混合开发框架|Flutter多引擎&dart多入口设计实现

15 篇文章 0 订阅
4 篇文章 1 订阅

仿照工行投资理财页面,使用Flutter实现。通过此讲述混合开发中,项目设计中,需求下如何创建多个Flutter引擎。Flutter引擎如何对应各自的dart入口,并实现每个Flutter引擎下路由切换页面。从而完成Flutter项目架构的设计搭建。
在这里插入图片描述

Flutter项目混合架构

FlutterFragment普通实现设计

在这里插入图片描述

系统有提供用来容放Flutter UI的容器,即FlutterFragment继承自androidx.fragment.app.Fragment。FlutterFragment作为FlutterEngine控制面提供Android资源和生命周期事件,并会attach到Activity。FlutterFragment终以内部方法public <T extends FlutterFragment> T build()反射获取Fragment实例。并作为当前Activity页面一部分显示出来。
说白了,就是使用混合开发。从原生项目转入到Flutter项目中,是将Flutter项目UI作为原生项目(如Activity)显示页面的一部分(撑满整个页面)来实现。

解释截图中代码片逻辑含义

红圈5, withCachedEngine(id) 中的 id ,有被FlutterEngineCache.getInstance().put(id, flutterEngine).get(id)用到,表示会将该id作为缓存FlutterEngine实例的键值对key。

追踪代码withCachedEngine(id)的执行,在FlutterFragment源码中,静态内部类构造方法CachedEngineFragmentBuilder中,id会被赋值给FlutterFragment全局变量String engineId。之后在反射获取FlutterFragment实例逻辑的同时,储到FlutterFragment的Bundle中。

FlutterFragment中方法getCachedEngineId,对外提供获取该id

FlutterActivityAndFragmentDelegate在Activity启动过程会执行onAttach方法,内部会执行到方法setupFlutterEngine中通过该id获取已缓存的FlutterEngine实例。这个是id的使用目的。

红圈5, shouldAttachEngineToActivity(true) 设置true,目的则是同上面逻辑分析,执行到onAttach方法时,则会执行下面代码片【使用获取到的已缓存的FlutterEngine实例,将已附着插件资源的Flutter引擎附着到Activity中,且生命周期与Activity同步】

Log.v(TAG, "Attaching FlutterEngine to the Activity that owns this delegate.");
flutterEngine.getActivityControlSurface().attachToActivity(this, host.getLifecycle());

系统FlutterFragment自带普通设计实现

  • FlutterEngine实例的创建,缓存。如红圈3和4.
  • 使用引擎实例配置默认(初始态)的路由path,如/fragment-icbc。如红圈1。
  • 使用引擎实例配置进入到Flutter-dart代码的入口。如红圈2。
  • 创建MethodChannel实例,并传入设置通道名称name。MethodChannel实例.setMethodCallHandler配置Flutter端向原生端的通信监听。

以上配置完成后,在Flutter项目源码中,dart代码入口文件main.dart。使用路由实例.push(name: window.defaultRouteName);,即可将Flutter项目首页展示原生项目已配置的默认(初始态)路由path对应的页面。

自定义FlutterFragment

源码展示

Flutter多引擎设计

Flutter的多引擎设计,利用Flutter中引擎的缓存容器FlutterEngineCache实现。

// 这里定了方法:用来初始化创建,新建flutter引擎实例。
private fun initFlutterEngine(context: Context, moduleName/**缓存到FlutterEngineCache的key*/: String) {
  var flutterEngine = FlutterEngine(context, FlutterLoader(), FlutterJNI())
  // ...省略 MethodChannel 的配置..
  flutterEngine.dartExecutor.
      executeDartEntrypoint(DartExecutor.DartEntrypoint(FlutterLoader().findAppBundlePath(), moduleName/**因为入口方法名,配置在这里了!*/))
}
// DartExecutor.java
// 系统源码中,有介绍 `dartEntrypointFunctionName`是dart入口方法名,且在DartEntrypoint构造方法中传入并赋值。
/** The name of a Dart function to execute. */
 public final String dartEntrypointFunctionName;

对已创建的Flutter引擎,之后使用FlutterEngineCache缓存起来。此时moduleName则对应dart入口方法名
【注:Native和Flutter通信,MethodChannel配置的name须一致。】

Flutter dart入口设计

在Flutter项目入口文件main.dart中,仿照默认初始入口定义规范

void main() {
  runApp(const FinanceApp());
}

在同一Flutter项目,自定义其他dart入口

// 定义新的dart入口,需要使用注解 @pragma('vm:entry-point')。其他不变。
('vm:entry-point')
void finance() {
  runApp(const FinanceApp());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值