背景
在我的flutter
项目中,从A组件导航到B组件后,B组件在软键盘弹起与收起的时候,A组件会不断调用didUpdateWidget
和build
。
初步排查
起初以为是路由的问题,经过排查后发现,Navigator
确实存在历史问题,会导致oldWidget
的rebuild
。
在1.17版本之后,这个问题已经被修复了,开发者不再需要额外的工作即可避免。
发现端倪
继续排查了很多地方,本以为可能出现问题的菜单组件、MediaQuery
的不合适的调用等等,都没有发现问题。
开始从下往上思考:如果组件本身没有调用setState
,没有继承InheritedWidget
,那发生预期外的生命周期函数调用,一定是它的context
在其他地方发生预期外的使用了。
找到凶手
搜索A组件里所有用到context
的地方,果不其然,凶手找到了:
precacheImage(NetworkImage(Constants.bgUrl), context);
复制代码
进入precacheImage
的源码后,很容易找到context
被注册到了MediaQuery.maybeOf
,剩下的就很好理解了:
MediaQuery
继承自InheritedWidget
;
软键盘调用时,MediaQueryData
会变化,所有通过MediaQuery.maybeOf
和MediaQuery.of
注册的组件都会更新。
总结
- 深入理解
Flutter
的生命周期和更新逻辑,在遇到相关的问题时总是能从源码和原理上找到解决办法。 - 保护好组件的
context
。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END