Flutter 2,面试官问的那些 Android 原理你都懂吗
所以就像例子上所示,你可以在一个
Activity上显示两个独立的 FlutterView 。
这其实得益于通过 FlutterEngineGroup 生成的 FlutterEngine 可以共享 GPU 上下文, font metrics 和 isolate group snapshot ,从而实现了更快的初始速度和更低的内存占用。
下图是使用官方实例打开 16 个页面之后的内存使用情况,并且每个页面成功返回且没有出现黑屏。
简单的使用介绍
使用 FlutterEngineGroup 首先需要创建一个 FlutterEngineGroup 单例对象,之后每当需要创建 Engine 时,就通过它的 createAndRunEngine(activity, dartEntrypoint) 来创建对应的 FlutterEngine 。
val app = activity.applicationContext as App// This has to be lazy to avoid creation before the FlutterEngineGroup.val dartEntrypoint =DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(), entrypoint)engine = app.engines.createAndRunEngine(activity, dartEntrypoint)this.delegate = delegatechannel = MethodChannel(engine.dartExecutor.binaryMessenger, "multiple-flutters")
以官方 Demo 的这段代码为例子:
1、首先通过 findAppBundlePath 和 entrypoint 创建出 DartEntrypoint 对象,这里的 findAppBundlePath 主要就是默认的 flutter_assets 目录;而 entrypoint 其实就是 dart 代码里启动方法的名称;也就是绑定了在 dart 中 runApp 的方法。
///kotlinapp.engines.createAndRunEngine(pathToBundle, "topMain")
///dart@pragma('vm:entry-point')void topMain() => runApp(MyApp());
2、通过上面创建的 dartEntrypoint 和 context ,使用 FlutterEngineGroup 就可以创建出对应的 FlutterEngine ,其实在内部就是通过FlutterJNI.nativeSpawn 和原有的引擎交互,得到新的 Long 地址 id。
在 C++ 层类似
于原有的 RunBundleAndSnapshotFromLibrary 方法,但是它不能更改包路径或者 asset ,所以只能加载同一份 AOT 文件,这里得到的指针地址就是一个新的 AndroidShellHolder 。
3、最后利用生成的 FlutterEngine 的 binaryMessenger 来得到一个 MethodChannel 用于原生和 dart 之间的通信。
通过上述流程得到的 Engine ,自然就可以直接用于渲染运行新的 Flutter UI,比如直接继承 FlutterActivity ,然后 override provideFlutterEngine 方法返回得到的 Engine 。
class SingleFlutterActivity : FlutterActivity()
·······
override fun provideFlutterEngine(context: Context): FlutterEngine? {return engine}
}











评论