开启编程成长之旅!这是我参与「编程 · 12 月更文挑战」的第8天,点击查看活动详情
日更计划,掏空自己。这篇对最新的 Flutter 版本也还有用,所以放出来给大家避坑。
起因
在之前 Flutter 2.5.3 升级 Flutter 2.10.5 之后的 App 版本,新增了一个奇怪的崩溃问题,如下图
过程
Flutter 源码定位
看崩溃记录,是在 Flutter 源码上,从 Flutter 源码中找到问题暴露的代码所在处 main 分支下 FlutterTextInputPlugin
崩溃所在代码下图所示:
看起来问题只能出在 _viewController
上了,_viewController
在这里获取的时候消失了 ...
Why?
想到这个版本之后是升级过 Flutter 版本号,所以就找到相应未升级前的版本(2.5.3)来对比,源码在这:2.5.3 tag 下的 FlutterTextInputPlugin
没有找到 - (UIView *)hostView
的定义,经代码分析得出,以前用的是 - (UIView *)keyWindow
这个方法,如下图:
那这个差异会导致问题吗?
但测试了几个 Flutter 需要输入框的地方,并没有复现问题。那崩溃是出在哪里?
日志分析
从几个用户的崩溃前日志来辅助排查问题,崩溃是在 Flutter 登录、抠图等,并没有特别的地方。
看了一下它前面的路由日志,发现是从搜索页进入的,搜索页也是 Flutter 开发的,而且搜索栏也会弹出键盘,立马试了一下:
问题复现了,是必现的问题。
而且如果手动隐藏掉第一个键盘,就不会产生崩溃。
问题原因
为什么 hostView
会消失呢?
究其原因,是被 flutter_boost 释放掉了。
看 flutter_boost 的源码,在这里:master 分支下 FBFlutterViewContainer
如上所示,在 dismiss
的时候,会执行以上方法,ENGINE.viewController
会设置为 nil。
由于 flutter_boost 单引擎设计,这个 viewController
就是上一个页面的 viewController
,这时候导致上一个页面的 FlutterTextInputPlugin
也丢失了 viewController
,导致崩溃。
而在 Flutter 2.5.3 中因为使用的是 keyWindow
,keyWindow
对象一直会存在,所以就不会崩溃。
修复方式
flutter_boost 单引擎机制导致不能从根本上解决这个问题的。
只能是检查 flutter_boost 开发的页面中,当页面因为 push
、present
导致的被隐藏或者失去焦点时,先把键盘释放掉,再执行相应跳转。
我司的修复方式,监听页面跳转事件,然后全局失去焦点,如下:
class AppGlobalPageVisibilityObserver extends GlobalPageVisibilityObserver {
...
@override
void onPagePush(Route route) {
super.onPagePush(route);
/// 规避 flutter boost 键盘崩溃
FocusManager.instance.primaryFocus.unfocus();
}
...
}
这确实是个隐患,不能确定后续开发过程中是否还会重复这样的崩溃问题,也不能确定是否还有类似的问题没有被发现。
后续
确定了 iOS 必现后,后面测试了 Android 上的情况,结果意外是正常的。
所以就了解了一下 flutter_boost Android 上的实现代码
可以看出,在 Android 上,flutter_boost 是用 detachFromActivity
从 Activity 上移除,而不是简单粗暴的设置 nil ... 所以这坑只有 iOS 会踩上,Android 跳了过去~
感谢阅读,如果对你有用请点个赞 ❤️
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!