FlutteriOSengine销毁实践
flutter从1.12开始⽀持add to app,相信有不少⼈使⽤该模式将Flutter集成到⾃⼰的项⽬⾥。打开⼀个Flutter页⾯很简单,如,Android中使⽤ateDefaultIntent(this))就可以打开Flutter页⾯,为了减少FlutterEngine初始化时间,⼀般会选择pre-warm FlutterEngine的⽅式。但是,当⽤户进⼊APP,⾄始⾄终都没有打开Flutter页⾯,FlutterEngine会⼀直存在内存中(如果对pre-warming FlutterEngine需要多少内存可以查看官⽅的测试数据),造成内存浪费。更糟糕的情况,FlutternEngine⼀直存在内存中得不到回收,内存不⾜的时候甚⾄会发⽣OOM。
之前在接⼊旅⾏⾸页的时候,我们使⽤的是延迟加载flutter engine的⽅式,但是engine⼀直⽆法释放,原因是pigeon代码在传⼊binaryMessenger的时候内部类会强引⽤,导致viewController⼀直⽆法deinit
image2021-1-26_14-47-39.png
这⾥我写了⼀个弱代理模式,打破之间的强引⽤:
image2021-1-26_15-12-38.png
延迟创建FlutterEngine
本次探索实践了新⽅法,为了解决pre-warm FlutterEngine可能会造成内存浪费的问题,可以在⽤户第⼀次打开Flutter页⾯时才创建FlutterEngine,将其缓存起来,减少⽤户再次打开Flutter页⾯时FlutterEngine的初始化时间。但是,延迟创建FlutterEngine会出现在第⼀个Flutter帧渲染出来前出现⽩屏的情况,为了优化⽤户体验可以为页⾯加上Splash Screen。下⾯看看在iOS中实现(android同理)。
由于FlutterViewController没有提供类似Android中provideFlutterEngine的⽅法,所以需要实现⾃⼰Container View Controller,先显⽰Splash Screen,然后创建并缓存FlutterEngine,再创建FlutterViewController。
class BaseRootFlutterViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let splashViewController = SplashViewControler()
splashViewController!.willMove(toParent: self)
addChild(splashViewController!)
splashViewController!.view.frame = self.view.bounds
view.addSubview(splashViewController!.view)
flutter开发appsplashViewController!.didMove(toParent: self)
image2021-1-26_15-15-17.png
image2021-1-26_15-15-33.png
image2021-1-26_15-6-30.png
所有VC均释放
以上
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论